"use client"

import { z } from "zod"
import { useEffect, useMemo, useRef, useState } from "react"
import { format, parseISO } from "date-fns"
import { ptBR } from "date-fns/locale"
import type { Doc, Id } from "@/convex/_generated/dataModel"
import type { TicketPriority, TicketQueueSummary } from "@/lib/schemas/ticket"
import { useMutation, useQuery } from "convex/react"
import { api } from "@/convex/_generated/api"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { useAuth } from "@/lib/auth-client"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { FieldSet, FieldGroup, Field, FieldLabel, FieldError } from "@/components/ui/field"
import { useForm } from "react-hook-form"
import { zodResolver } from "@/lib/zod-resolver"
import { toast } from "sonner"
import { Spinner } from "@/components/ui/spinner"
import { Dropzone } from "@/components/ui/dropzone"
import { RichTextEditor, sanitizeEditorHtml } from "@/components/ui/rich-text-editor"
import { PriorityIcon } from "@/components/tickets/priority-select"
import { CategorySelectFields } from "@/components/tickets/category-select"
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { SearchableCombobox, type SearchableComboboxOption } from "@/components/ui/searchable-combobox"
import { Calendar } from "@/components/ui/calendar"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { useDefaultQueues } from "@/hooks/use-default-queues"
import { useLocalTimeZone } from "@/hooks/use-local-time-zone"
import { cn } from "@/lib/utils"
import { priorityStyles } from "@/lib/ticket-priority-style"
import { normalizeCustomFieldInputs } from "@/lib/ticket-form-helpers"
import type { TicketFormDefinition, TicketFormFieldDefinition } from "@/lib/ticket-form-types"
import { Calendar as CalendarIcon, ListChecks, Plus, Trash2 } from "lucide-react"
import { TimePicker } from "@/components/ui/time-picker"
import { VISIT_KEYWORDS } from "@/lib/ticket-matchers"
import { Checkbox } from "@/components/ui/checkbox"

type TriggerVariant = "button" | "card"

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

type ChecklistDraftItem = {
  id: string
  text: string
  required: boolean
}

type ChecklistTemplateOption = {
  id: Id<"ticketChecklistTemplates">
  name: string
  company: { id: Id<"companies">; name: string } | null
  items: Array<{ id: string; text: string; required: boolean }>
}

function getInitials(name: string | null | undefined, fallback: string): string {
  const normalizedName = (name ?? "").trim()
  if (normalizedName.length > 0) {
    const parts = normalizedName.split(/\s+/).slice(0, 2)
    const initials = parts.map((part) => part.charAt(0).toUpperCase()).join("")
    if (initials.length > 0) {
      return initials
    }
  }
  const normalizedFallback = (fallback ?? "").trim()
  return normalizedFallback.length > 0 ? normalizedFallback.charAt(0).toUpperCase() : "?"
}

function toHtml(text: string) {
  const escaped = text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;")
  return `<p>${escaped.replace(/\n/g, "<br />")}</p>`
}

type RequesterPreviewProps = {
  customer: CustomerOption | null
  company: { id: string; name: string; isAvulso?: boolean } | null
}

function RequesterPreview({ customer, company }: RequesterPreviewProps) {
  if (!customer) {
    return (
      <div className="mb-3 rounded-xl border border-dashed border-border/80 bg-muted/40 px-3 py-2 text-xs text-muted-foreground">
        Selecione um solicitante para visualizar os detalhes aqui.
      </div>
    )
  }

  const initials = getInitials(customer.name, customer.email)
  const companyLabel = customer.companyName ?? company?.name ?? "Sem empresa"

  return (
    <div className="mb-3 flex flex-col gap-2 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 shadow-sm">
      <div className="flex items-center gap-3">
        <Avatar className="size-9 border border-border/60 bg-white text-sm font-semibold uppercase">
          <AvatarFallback>{initials}</AvatarFallback>
        </Avatar>
        <div className="min-w-0 space-y-0.5">
          <p className="truncate font-semibold text-foreground">{customer.name || customer.email}</p>
          <p className="truncate text-xs text-muted-foreground">{customer.email}</p>
        </div>
      </div>
      <div className="flex items-center gap-2">
        <Badge variant="outline" className="rounded-full border-slate-200 px-2.5 py-0.5 text-[10px] uppercase tracking-wide text-muted-foreground">
          {companyLabel}
        </Badge>
      </div>
    </div>
  )
}

const NO_COMPANY_VALUE = "__no_company__"

const schema = z.object({
  subject: z.string().default(""),
  description: z.string().default(""),
  priority: z.enum(["LOW", "MEDIUM", "HIGH", "URGENT"]).default("MEDIUM"),
  channel: z.enum(["EMAIL", "WHATSAPP", "CHAT", "PHONE", "API", "MANUAL"]).default("MANUAL"),
  queueName: z.string().nullable().optional(),
  visitDate: z.string().nullable().optional(),
  visitTime: z.string().nullable().optional(),
  assigneeId: z.string().nullable().optional(),
  companyId: z.string().optional(),
  requesterId: z.string().min(1, "Selecione um solicitante"),
  categoryId: z.string().min(1, "Selecione uma categoria"),
  subcategoryId: z.string().min(1, "Selecione uma categoria secundária"),
})

export function NewTicketDialog({
  triggerClassName,
  triggerVariant = "button",
}: {
  triggerClassName?: string
  triggerVariant?: TriggerVariant
} = {}) {
  const [open, setOpen] = useState(false)
  const [loading, setLoading] = useState(false)
  const calendarTimeZone = useLocalTimeZone()
  const form = useForm<z.infer<typeof schema>>({
    resolver: zodResolver(schema),
    defaultValues: {
      subject: "",
      description: "",
      priority: "MEDIUM",
      channel: "MANUAL",
      queueName: null,
      visitDate: null,
      visitTime: null,
      assigneeId: null,
      companyId: NO_COMPANY_VALUE,
      requesterId: "",
      categoryId: "",
      subcategoryId: "",
    },
    mode: "onTouched",
  })
  const { convexUserId, isStaff, role, session, machineContext } = useAuth()
  const sessionUser = session?.user ?? null
  const queuesEnabled = Boolean(isStaff && convexUserId)
  useDefaultQueues(DEFAULT_TENANT_ID)
  const queuesRemote = useQuery(
    api.queues.summary,
    queuesEnabled ? { tenantId: DEFAULT_TENANT_ID, viewerId: convexUserId as Id<"users"> } : "skip"
  )
  const queues = useMemo(
    () => (Array.isArray(queuesRemote) ? (queuesRemote as TicketQueueSummary[]) : []),
    [queuesRemote]
  )
  const create = useMutation(api.tickets.create)
  const addComment = useMutation(api.tickets.addComment)
  const staffRaw = useQuery(api.users.listAgents, { tenantId: DEFAULT_TENANT_ID }) as Doc<"users">[] | undefined
  const staff = useMemo(
    () => (staffRaw ?? []).sort((a, b) => a.name.localeCompare(b.name, "pt-BR")),
    [staffRaw]
  )

  const directoryQueryEnabled = queuesEnabled && Boolean(convexUserId)
  const companiesRemote = useQuery(
    api.companies.list,
    directoryQueryEnabled ? { tenantId: DEFAULT_TENANT_ID, 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 ensureTicketFormDefaultsMutation = useMutation(api.tickets.ensureTicketFormDefaults)
  const hasEnsuredFormsRef = useRef(false)

  useEffect(() => {
    if (!convexUserId || hasEnsuredFormsRef.current) return
    hasEnsuredFormsRef.current = true
    ensureTicketFormDefaultsMutation({
      tenantId: DEFAULT_TENANT_ID,
      actorId: convexUserId as Id<"users">,
    }).catch((error) => {
      console.error("Falha ao preparar formulários personalizados", error)
      hasEnsuredFormsRef.current = false
    })
  }, [convexUserId, ensureTicketFormDefaultsMutation])

  const companyValue = form.watch("companyId") ?? NO_COMPANY_VALUE

  const formsRemote = useQuery(
    api.tickets.listTicketForms,
    convexUserId
      ? {
          tenantId: DEFAULT_TENANT_ID,
          viewerId: convexUserId as Id<"users">,
          companyId: companyValue !== NO_COMPANY_VALUE ? (companyValue as Id<"companies">) : undefined,
        }
      : "skip"
  ) as TicketFormDefinition[] | undefined

  const checklistTemplates = useQuery(
    api.checklistTemplates.listActive,
    convexUserId
      ? {
          tenantId: DEFAULT_TENANT_ID,
          viewerId: convexUserId as Id<"users">,
          companyId: companyValue !== NO_COMPANY_VALUE ? (companyValue as Id<"companies">) : undefined,
        }
      : "skip"
  ) as ChecklistTemplateOption[] | undefined

  const forms = useMemo<TicketFormDefinition[]>(() => {
    const fallback: TicketFormDefinition = {
      key: "default",
      label: "Chamado",
      description: "Formulário básico para abertura de chamados gerais.",
      fields: [],
    }
    if (!formsRemote || formsRemote.length === 0) {
      return [fallback]
    }
    const hasDefault = formsRemote.some((form) => form.key === fallback.key)
    if (hasDefault) {
      return formsRemote
    }
    return [fallback, ...formsRemote]
  }, [formsRemote])

  const [selectedFormKey, setSelectedFormKey] = useState<string>("default")
  const [customFieldValues, setCustomFieldValues] = useState<Record<string, unknown>>({})
  const [openCalendarField, setOpenCalendarField] = useState<string | null>(null)
  const [visitDatePickerOpen, setVisitDatePickerOpen] = useState(false)
  const [manualChecklist, setManualChecklist] = useState<ChecklistDraftItem[]>([])
  const [appliedChecklistTemplateIds, setAppliedChecklistTemplateIds] = useState<string[]>([])
  const [checklistTemplateToApply, setChecklistTemplateToApply] = useState<string>("")
  const [checklistItemText, setChecklistItemText] = useState("")
  const [checklistItemRequired, setChecklistItemRequired] = useState(true)

  const appliedChecklistTemplates = useMemo(() => {
    const selected = new Set(appliedChecklistTemplateIds.map(String))
    return (checklistTemplates ?? []).filter((tpl) => selected.has(String(tpl.id)))
  }, [appliedChecklistTemplateIds, checklistTemplates])

  const checklistTemplatePreviewItems = useMemo(
    () =>
      appliedChecklistTemplates.flatMap((tpl) =>
        (tpl.items ?? []).map((item) => ({
          key: `${String(tpl.id)}:${item.id}`,
          text: item.text,
          required: item.required,
          templateName: tpl.name,
        }))
      ),
    [appliedChecklistTemplates]
  )

  const selectedForm = useMemo(() => forms.find((formDef) => formDef.key === selectedFormKey) ?? forms[0], [forms, selectedFormKey])

  const handleFormSelection = (key: string) => {
    setSelectedFormKey(key)
    setCustomFieldValues({})
  }

  const handleCustomFieldChange = (field: TicketFormFieldDefinition, value: unknown) => {
    setCustomFieldValues((prev) => ({
      ...prev,
      [field.id]: value,
    }))
  }

  const customersRemote = useQuery(
    api.users.listCustomers,
    directoryQueryEnabled ? { tenantId: DEFAULT_TENANT_ID, viewerId: convexUserId as Id<"users"> } : "skip"
  )
  const rawCustomers = useMemo(
    () => (Array.isArray(customersRemote) ? (customersRemote as CustomerOption[]) : []),
    [customersRemote]
  )
  const viewerCustomer = useMemo<CustomerOption | null>(() => {
    if (!convexUserId || !sessionUser) return null
    return {
      id: convexUserId,
      name: sessionUser.name ?? sessionUser.email,
      email: sessionUser.email,
      role: sessionUser.role ?? "customer",
      companyId: machineContext?.companyId ?? null,
      companyName: null,
      companyIsAvulso: false,
      avatarUrl: sessionUser.avatarUrl,
    }
  }, [convexUserId, sessionUser, machineContext?.companyId])
  const customers = useMemo(() => {
    if (!viewerCustomer) return rawCustomers
    const exists = rawCustomers.some((customer) => customer.id === viewerCustomer.id)
    return exists ? rawCustomers : [...rawCustomers, viewerCustomer]
  }, [rawCustomers, viewerCustomer])
  const [attachments, setAttachments] = useState<Array<{ storageId: string; name: string; size?: number; type?: string }>>([])
  const [customersInitialized, setCustomersInitialized] = useState(false)
  const attachmentsTotalBytes = useMemo(
    () => attachments.reduce((acc, item) => acc + (item.size ?? 0), 0),
    [attachments]
  )
  const priorityValue = form.watch("priority") as TicketPriority
  const queueValue = form.watch("queueName") ?? "NONE"
  const visitDateValue = form.watch("visitDate") ?? null
  const visitTimeValue = form.watch("visitTime") ?? null
  const assigneeValue = form.watch("assigneeId") ?? null
  const assigneeSelectValue = assigneeValue ?? "NONE"
  const requesterValue = form.watch("requesterId") ?? ""
  const categoryIdValue = form.watch("categoryId")
  const subcategoryIdValue = form.watch("subcategoryId")
  const isSubmitted = form.formState.isSubmitted

  const normalizedQueueName =
    typeof queueValue === "string" && queueValue !== "NONE" ? queueValue.toLowerCase() : ""
  const isVisitQueue = useMemo(
    () => VISIT_KEYWORDS.some((keyword) => normalizedQueueName.includes(keyword)),
    [normalizedQueueName]
  )
  const visitDate = useMemo(() => {
    if (!visitDateValue) return null
    const timeSegment =
      typeof visitTimeValue === "string" && visitTimeValue.length > 0 ? visitTimeValue : "00:00"
    const normalizedTime = timeSegment.length === 5 ? `${timeSegment}:00` : timeSegment
    try {
      return parseISO(`${visitDateValue}T${normalizedTime}`)
    } catch {
      return null
    }
  }, [visitDateValue, visitTimeValue])

  useEffect(() => {
    if (isVisitQueue) return
    form.setValue("visitDate", null, { shouldDirty: false, shouldTouch: false })
    form.setValue("visitTime", null, { shouldDirty: false, shouldTouch: false })
  }, [form, isVisitQueue])

  const companyOptions = useMemo(() => {
    const map = new Map<string, { id: 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)}`
      map.set(company.id, {
        id: company.id,
        name: label,
        isAvulso: false,
        keywords: company.slug ? [company.slug] : [],
      })
    })
    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, {
          id: customer.companyId,
          name: label,
          isAvulso: customer.companyIsAvulso,
          keywords: [],
        })
      }
    })
    const base: Array<{ id: string; name: string; isAvulso?: boolean; keywords: string[] }> = [
      { id: NO_COMPANY_VALUE, name: "Sem empresa", keywords: ["sem empresa", "nenhuma"], isAvulso: false },
    ]
    const sorted = Array.from(map.values())
      .sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))
    return [...base, ...sorted]
  }, [companies, customers])

  const filteredCustomers = useMemo(() => {
    if (companyValue === NO_COMPANY_VALUE) {
      return customers.filter((customer) => !customer.companyId)
    }
    return customers.filter((customer) => customer.companyId === companyValue)
  }, [companyValue, customers])

  const companyOptionMap = useMemo(
    () => new Map(companyOptions.map((option) => [option.id, option])),
    [companyOptions],
  )

  const companyComboboxOptions = useMemo<SearchableComboboxOption[]>(
    () =>
      companyOptions.map((option) => ({
        value: option.id,
        label: option.name,
        description: option.isAvulso ? "Empresa avulsa" : undefined,
        keywords: option.keywords,
      })),
    [companyOptions],
  )

  const selectedCompanyOption = useMemo(
    () => companyOptionMap.get(companyValue) ?? null,
    [companyOptionMap, companyValue],
  )

  const requesterById = useMemo(
    () => new Map(customers.map((customer) => [customer.id, customer])),
    [customers],
  )

  const selectedRequester = requesterById.get(requesterValue) ?? null

  const requesterComboboxOptions = useMemo<SearchableComboboxOption[]>(
    () =>
      filteredCustomers.map((customer) => ({
        value: customer.id,
        label: customer.name && customer.name.trim().length > 0 ? customer.name : customer.email,
        description: customer.email,
        keywords: [
          customer.email.toLowerCase(),
          customer.companyName?.toLowerCase?.() ?? "",
          customer.name?.toLowerCase?.() ?? "",
        ].filter(Boolean),
      })),
    [filteredCustomers],
  )

  const selectTriggerClass = "flex h-8 w-full items-center justify-between rounded-full border border-slate-300 bg-white px-3 text-sm font-medium text-neutral-800 shadow-sm focus:ring-0 data-[state=open]:border-[#00d6eb]"
  const selectItemClass = "flex items-center gap-2 rounded-md px-2 py-2 text-sm text-neutral-800 transition data-[state=checked]:bg-[#00e8ff]/15 data-[state=checked]:text-neutral-900 focus:bg-[#00e8ff]/10"
  const [assigneeInitialized, setAssigneeInitialized] = useState(false)
  const allowTicketMentions = useMemo(() => {
    const normalized = (role ?? "").toLowerCase()
    return normalized === "admin" || normalized === "agent" || normalized === "collaborator"
  }, [role])

  useEffect(() => {
    if (!open) {
      setCustomersInitialized(false)
      setManualChecklist([])
      setAppliedChecklistTemplateIds([])
      setChecklistTemplateToApply("")
      setChecklistItemText("")
      setChecklistItemRequired(true)
      form.setValue("companyId", NO_COMPANY_VALUE, { shouldDirty: false, shouldTouch: false })
      form.setValue("requesterId", "", { shouldDirty: false, shouldTouch: false })
      return
    }
    if (customersInitialized) return
    if (!customers.length) return
    let initialRequester = form.getValues("requesterId")
    if (!initialRequester || !customers.some((customer) => customer.id === initialRequester)) {
      if (convexUserId && customers.some((customer) => customer.id === convexUserId)) {
        initialRequester = convexUserId
      } else {
        initialRequester = customers[0].id
      }
    }
    const selected = customers.find((customer) => customer.id === initialRequester) ?? null
    form.setValue("requesterId", initialRequester ?? "", { shouldDirty: false, shouldTouch: false })
    if (selected?.companyId) {
      form.setValue("companyId", selected.companyId, { shouldDirty: false, shouldTouch: false })
    } else {
      form.setValue("companyId", NO_COMPANY_VALUE, { shouldDirty: false, shouldTouch: false })
    }
    setCustomersInitialized(true)
  }, [open, customersInitialized, customers, convexUserId, form])

  useEffect(() => {
    if (!open || !customersInitialized) return
    const options = filteredCustomers
    if (options.length === 0) {
      if (requesterValue !== "") {
        form.setValue("requesterId", "", {
          shouldDirty: true,
          shouldTouch: true,
          shouldValidate: form.formState.isSubmitted,
        })
      }
      return
    }
    if (!options.some((customer) => customer.id === requesterValue)) {
      form.setValue("requesterId", options[0].id, {
        shouldDirty: true,
        shouldTouch: true,
        shouldValidate: form.formState.isSubmitted,
      })
    }
  }, [open, customersInitialized, filteredCustomers, requesterValue, form])

  useEffect(() => {
    if (requesterValue && form.formState.errors.requesterId) {
      form.clearErrors("requesterId")
    }
  }, [requesterValue, form])


  useEffect(() => {
    if (!open) {
      setAssigneeInitialized(false)
      setOpenCalendarField(null)
      setVisitDatePickerOpen(false)
      return
    }
    if (assigneeInitialized) return
    if (!convexUserId) return
    form.setValue("assigneeId", convexUserId, { shouldDirty: false, shouldTouch: false })
    setAssigneeInitialized(true)
  }, [open, assigneeInitialized, convexUserId, form])

  // Default queue to "Chamados" if available when opening
  useEffect(() => {
    if (!open) return
    const current = form.getValues("queueName")
    if (current) return
    const hasChamados = queues.some((q) => q.name === "Chamados")
    if (hasChamados) {
      form.setValue("queueName", "Chamados", { shouldDirty: false, shouldTouch: false })
    }
  }, [open, queues, form])

  const handleCategoryChange = (value: string) => {
    const previous = form.getValues("categoryId") ?? ""
    const next = value ?? ""
    form.setValue("categoryId", next, {
      shouldDirty: previous !== next && previous !== "",
      shouldTouch: true,
      shouldValidate: isSubmitted,
    })
    if (!isSubmitted) {
      form.clearErrors("categoryId")
    }
  }

  const handleSubcategoryChange = (value: string) => {
    const previous = form.getValues("subcategoryId") ?? ""
    const next = value ?? ""
    form.setValue("subcategoryId", next, {
      shouldDirty: previous !== next && previous !== "",
      shouldTouch: true,
      shouldValidate: isSubmitted,
    })
    if (!isSubmitted) {
      form.clearErrors("subcategoryId")
    }
  }

  const handleApplyChecklistTemplate = () => {
    const templateId = checklistTemplateToApply.trim()
    if (!templateId) return
    setAppliedChecklistTemplateIds((prev) => {
      if (prev.includes(templateId)) return prev
      return [...prev, templateId]
    })
    setChecklistTemplateToApply("")
  }

  const handleAddChecklistItem = () => {
    const text = checklistItemText.trim()
    if (!text) {
      toast.error("Informe o texto do item do checklist.", { id: "new-ticket" })
      return
    }
    if (text.length > 240) {
      toast.error("Item do checklist muito longo (máx. 240 caracteres).", { id: "new-ticket" })
      return
    }
    setManualChecklist((prev) => [...prev, { id: crypto.randomUUID(), text, required: checklistItemRequired }])
    setChecklistItemText("")
    setChecklistItemRequired(true)
  }

  async function submit(values: z.infer<typeof schema>) {
    if (!convexUserId) return

    const subjectTrimmed = (values.subject ?? "").trim()
    if (subjectTrimmed.length < 3) {
      form.setError("subject", { type: "min", message: "Informe um assunto com pelo menos 3 caracteres." })
      return
    }

    const sanitizedDescription = sanitizeEditorHtml(values.description ?? "")
    const plainDescription = sanitizedDescription.replace(/<[^>]*>/g, "").trim()
    if (plainDescription.length === 0) {
      form.setError("description", { type: "custom", message: "Descreva o contexto do chamado." })
      setLoading(false)
      return
    }

    const currentQueueName = values.queueName ?? ""
    const isVisitQueueOnSubmit =
      typeof currentQueueName === "string" &&
      VISIT_KEYWORDS.some((keyword) => currentQueueName.toLowerCase().includes(keyword))
    if (isVisitQueueOnSubmit) {
      if (!values.visitDate) {
        form.setError("visitDate", { type: "custom", message: "Informe a data da visita para chamados desta fila." })
        return
      }
      if (!values.visitTime) {
        form.setError("visitTime", { type: "custom", message: "Informe o horário da visita para chamados desta fila." })
        return
      }
    }

    let customFieldsPayload: Array<{ fieldId: Id<"ticketFields">; value: unknown }> = []
    if (selectedForm?.fields?.length) {
      const normalized = normalizeCustomFieldInputs(selectedForm.fields, customFieldValues)
      if (!normalized.ok) {
        toast.error(normalized.message, { id: "new-ticket" })
        setLoading(false)
        return
      }
      customFieldsPayload = normalized.payload
    }
    const checklistPayload = manualChecklist.map((item) => ({
      text: item.text.trim(),
      required: item.required,
    }))
    const invalidChecklist = checklistPayload.find((item) => item.text.length === 0 || item.text.length > 240)
    if (invalidChecklist) {
      toast.error("Revise os itens do checklist (texto obrigatório e até 240 caracteres).", { id: "new-ticket" })
      return
    }
    const checklistTemplateIds = appliedChecklistTemplateIds.map((id) => id as Id<"ticketChecklistTemplates">)

    setLoading(true)
    toast.loading("Criando ticket…", { id: "new-ticket" })
    try {
      const sel = queues.find((q) => q.name === values.queueName)
      const selectedAssignee = form.getValues("assigneeId") ?? null
      const requesterToSend = values.requesterId as Id<"users">
      let visitDateTimestamp: number | undefined
      if (isVisitQueueOnSubmit && values.visitDate && values.visitTime) {
        try {
          const timeSegment = values.visitTime.length === 5 ? `${values.visitTime}:00` : values.visitTime
          const parsed = parseISO(`${values.visitDate}T${timeSegment}`)
          visitDateTimestamp = parsed.getTime()
        } catch {
          visitDateTimestamp = undefined
        }
      }
      const id = await create({
        actorId: convexUserId as Id<"users">,
        tenantId: DEFAULT_TENANT_ID,
        subject: subjectTrimmed,
        priority: values.priority,
        channel: values.channel,
        queueId: sel?.id as Id<"queues"> | undefined,
        requesterId: requesterToSend,
        assigneeId: selectedAssignee ? (selectedAssignee as Id<"users">) : undefined,
        categoryId: values.categoryId as Id<"ticketCategories">,
        subcategoryId: values.subcategoryId as Id<"ticketSubcategories">,
        formTemplate: selectedFormKey !== "default" ? selectedFormKey : undefined,
        checklist: checklistPayload.length > 0 ? checklistPayload : undefined,
        checklistTemplateIds: checklistTemplateIds.length > 0 ? checklistTemplateIds : undefined,
        customFields: customFieldsPayload.length > 0 ? customFieldsPayload : undefined,
        visitDate: visitDateTimestamp,
      })
      const summaryFallback = subjectTrimmed
      const bodyHtml = plainDescription.length > 0 ? sanitizedDescription : toHtml(summaryFallback)
      const MAX_COMMENT_CHARS = 20000
      const plainForLimit = (plainDescription.length > 0 ? plainDescription : summaryFallback).trim()
      if (plainForLimit.length > MAX_COMMENT_CHARS) {
        toast.error(`Descrição muito longa (máx. ${MAX_COMMENT_CHARS} caracteres)`, { id: "new-ticket" })
        setLoading(false)
        return
      }
      if (attachments.length > 0 || bodyHtml.trim().length > 0) {
        const typedAttachments = attachments.map((a) => ({
          storageId: a.storageId as unknown as Id<"_storage">,
          name: a.name,
          size: a.size,
          type: a.type,
        }))
        await addComment({ ticketId: id as Id<"tickets">, authorId: convexUserId as Id<"users">, visibility: "INTERNAL", body: bodyHtml, attachments: typedAttachments })
      }
      toast.success("Ticket criado!", { id: "new-ticket" })
      setOpen(false)
      form.reset({
        subject: "",
        description: "",
        priority: "MEDIUM",
        channel: "MANUAL",
        queueName: null,
        assigneeId: convexUserId ?? null,
        categoryId: "",
        subcategoryId: "",
        visitDate: null,
        visitTime: null,
      })
      form.clearErrors()
      setSelectedFormKey("default")
      setCustomFieldValues({})
      setAssigneeInitialized(false)
      setAttachments([])
      setManualChecklist([])
      setAppliedChecklistTemplateIds([])
      setChecklistTemplateToApply("")
      setChecklistItemText("")
      setChecklistItemRequired(true)
      // Navegar para o ticket recém-criado
      window.location.href = `/tickets/${id}`
    } catch {
      toast.error("Não foi possível criar o ticket.", { id: "new-ticket" })
    } finally {
      setLoading(false)
    }
  }

  const cardTrigger = (
    <button
      type="button"
      className={cn(
        "rounded-2xl border border-slate-900 bg-neutral-950 px-4 py-4 text-left text-white shadow-lg shadow-black/30 transition hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/40",
        "flex h-28 min-w-[220px] flex-1 flex-col justify-between",
        triggerClassName
      )}
    >
      <span className="text-xs font-semibold uppercase tracking-wide text-white/60">Atalho</span>
      <div className="space-y-1">
        <p className="text-lg font-semibold leading-tight">Novo ticket</p>
        <p className="text-xs text-white/70">Abrir chamado manualmente</p>
      </div>
    </button>
  )

  const buttonTrigger = (
    <Button
      size="sm"
      className={cn(
        "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",
        triggerClassName
      )}
    >
      Novo ticket
    </Button>
  )

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        {triggerVariant === "card"
          ? cardTrigger
          : buttonTrigger}
      </DialogTrigger>
      <DialogContent className="max-w-4xl gap-0 overflow-hidden rounded-3xl border border-slate-200 bg-white p-0 shadow-2xl lg:max-w-5xl">
        <div className="max-h-[88vh] overflow-y-auto">
          <div className="space-y-5 px-6 pt-7 pb-12 sm:px-8 md:px-10">
            <form className="space-y-6" onSubmit={form.handleSubmit(submit)}>
              <div className="border-b border-slate-200 pb-5">
                <DialogHeader className="gap-1.5 p-0">
                  <DialogTitle className="text-xl font-semibold text-neutral-900">Novo ticket</DialogTitle>
                  <DialogDescription className="text-sm text-neutral-600">
                    Preencha as informações básicas para abrir um chamado.
                  </DialogDescription>
                </DialogHeader>
              </div>
              {forms.length > 1 ? (
                <div className="rounded-xl border border-slate-200 bg-slate-50 px-4 py-4">
                  <p className="text-sm font-semibold text-neutral-800">Tipo de solicitação</p>
                  <div className="mt-2 flex flex-wrap gap-2">
                    {forms.map((formDef) => (
                      <Button
                        key={formDef.key}
                        type="button"
                        variant={selectedFormKey === formDef.key ? "default" : "outline"}
                        size="sm"
                        onClick={() => handleFormSelection(formDef.key)}
                      >
                        {formDef.label}
                      </Button>
                    ))}
                  </div>
                  {selectedForm?.description ? (
                    <p className="mt-2 text-xs text-neutral-500">{selectedForm.description}</p>
                  ) : null}
                </div>
              ) : null}

              <FieldSet>
                <FieldGroup className="lg:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]">
                  <div className="space-y-4">
                    <Field>
                      <FieldLabel htmlFor="subject" className="flex items-center gap-1">
                        Assunto <span className="text-destructive">*</span>
                      </FieldLabel>
                      <Input id="subject" {...form.register("subject")} placeholder="Ex.: Erro 500 no portal" />
                      <FieldError errors={form.formState.errors.subject ? [{ message: form.formState.errors.subject.message }] : []} />
                    </Field>
                    <Field>
                      <FieldLabel className="flex items-center gap-1">
                        Descrição <span className="text-destructive">*</span>
                      </FieldLabel>
                      <RichTextEditor
                        value={form.watch("description") || ""}
                        onChange={(html) =>
                          form.setValue("description", html, {
                            shouldDirty: true,
                            shouldTouch: true,
                            shouldValidate: form.formState.isSubmitted,
                          })
                        }
                        placeholder="Detalhe o problema, passos para reproduzir, links, etc."
                        ticketMention={{ enabled: allowTicketMentions }}
                      />
                      <FieldError
                        errors={
                          form.formState.errors.description
                            ? [{ message: form.formState.errors.description.message }]
                            : []
                        }
                      />
                    </Field>
                    <Field>
                      <FieldLabel>Anexos</FieldLabel>
                      <Dropzone
                        onUploaded={(files) => setAttachments((prev) => [...prev, ...files])}
                        className="space-y-1.5 [&>div:first-child]:rounded-2xl [&>div:first-child]:p-4 [&>div:first-child]:pb-5 [&>div:first-child]:shadow-sm"
                        currentFileCount={attachments.length}
                        currentTotalBytes={attachmentsTotalBytes}
                      />
                      <FieldError className="mt-1">Formatos comuns de imagem e documentos são aceitos.</FieldError>
                    </Field>
                  </div>
                  <div className="space-y-4">
                    <Field>
                      <FieldLabel>Empresa</FieldLabel>
                      <SearchableCombobox
                        value={companyValue}
                        onValueChange={(nextValue) => {
                          const normalizedValue = nextValue ?? NO_COMPANY_VALUE
                          const nextCustomers =
                            normalizedValue === NO_COMPANY_VALUE
                              ? customers.filter((customer) => !customer.companyId)
                              : customers.filter((customer) => customer.companyId === normalizedValue)
                          form.setValue("companyId", normalizedValue, {
                            shouldDirty: normalizedValue !== companyValue,
                            shouldTouch: true,
                          })
                          if (nextCustomers.length === 0) {
                            form.setValue("requesterId", "", {
                              shouldDirty: true,
                              shouldTouch: true,
                              shouldValidate: form.formState.isSubmitted,
                            })
                          } else if (!nextCustomers.some((customer) => customer.id === requesterValue)) {
                            const fallbackRequester = nextCustomers[0]
                            form.setValue("requesterId", fallbackRequester.id, {
                              shouldDirty: true,
                              shouldTouch: true,
                              shouldValidate: form.formState.isSubmitted,
                            })
                          }
                        }}
                        options={companyComboboxOptions}
                        placeholder="Selecionar empresa"
                        renderValue={(option) =>
                          option ? (
                            <span className="truncate">{option.label}</span>
                          ) : (
                            <span className="text-muted-foreground">Selecionar empresa</span>
                          )
                        }
                        renderOption={(option) => {
                          const meta = companyOptionMap.get(option.value)
                          return (
                            <div className="flex items-center justify-between gap-3">
                              <div className="flex flex-col">
                                <span className="font-medium text-foreground">{option.label}</span>
                                {meta?.keywords?.length ? (
                                  <span className="text-xs text-muted-foreground">{meta.keywords[0]}</span>
                                ) : null}
                              </div>
                              {meta?.isAvulso ? (
                                <Badge variant="outline" className="rounded-full px-2 py-0.5 text-[10px] uppercase tracking-wide">
                                  Avulsa
                                </Badge>
                              ) : null}
                            </div>
                          )
                        }}
                      />
                    </Field>
                    <Field>
                      <FieldLabel className="flex items-center gap-1">
                        Solicitante <span className="text-destructive">*</span>
                      </FieldLabel>
                      <SearchableCombobox
                        value={requesterValue || null}
                        onValueChange={(nextValue) => {
                          if (nextValue === null) {
                            form.setValue("requesterId", "", {
                              shouldDirty: true,
                              shouldTouch: true,
                              shouldValidate: form.formState.isSubmitted,
                            })
                            return
                          }
                          if (nextValue !== requesterValue) {
                            form.setValue("requesterId", nextValue, {
                              shouldDirty: true,
                              shouldTouch: true,
                              shouldValidate: form.formState.isSubmitted,
                            })
                          }
                          const selection = requesterById.get(nextValue)
                          if (selection) {
                            const nextCompanyId = selection.companyId ?? NO_COMPANY_VALUE
                            if (nextCompanyId !== companyValue) {
                              form.setValue("companyId", nextCompanyId, {
                                shouldDirty: true,
                                shouldTouch: true,
                              })
                            }
                          }
                        }}
                        options={requesterComboboxOptions}
                        placeholder={filteredCustomers.length === 0 ? "Nenhum usuário disponível" : "Selecionar solicitante"}
                        searchPlaceholder="Buscar por nome ou e-mail..."
                        disabled={filteredCustomers.length === 0}
                        renderValue={(option) => {
                          if (!option) return <span className="text-muted-foreground">Selecionar solicitante</span>
                          return (
                            <div className="flex w-full flex-wrap items-start gap-2">
                              <div className="flex min-w-0 flex-1 flex-col">
                                <span className="truncate font-medium text-foreground">{option.label}</span>
                                {option.description ? (
                                  <span className="truncate text-xs text-muted-foreground">{option.description}</span>
                                ) : null}
                              </div>
                              {selectedCompanyOption && selectedCompanyOption.id !== NO_COMPANY_VALUE ? (
                                <Badge
                                  variant="outline"
                                  className="hidden min-w-0 max-w-full truncate rounded-full px-2.5 py-0.5 text-[10px] uppercase tracking-wide text-muted-foreground sm:ml-auto sm:inline-flex sm:max-w-[45%]"
                                >
                                  {selectedCompanyOption.name}
                                </Badge>
                              ) : null}
                            </div>
                          )
                        }}
                        renderOption={(option) => {
                          const record = requesterById.get(option.value)
                          const initials = getInitials(record?.name, record?.email ?? option.label)
                          return (
                            <div className="flex items-center gap-3">
                              <Avatar className="size-8 border border-border/60">
                                <AvatarFallback className="text-xs font-semibold uppercase">{initials}</AvatarFallback>
                              </Avatar>
                              <div className="min-w-0 flex-1">
                                <p className="truncate font-medium text-foreground">{option.label}</p>
                                <p className="truncate text-xs text-muted-foreground">{record?.email ?? option.description}</p>
                              </div>
                              {record?.companyName ? (
                                <Badge variant="outline" className="hidden rounded-full px-2 py-0.5 text-[10px] uppercase tracking-wide md:inline-flex">
                                  {record.companyName}
                                </Badge>
                              ) : null}
                            </div>
                          )
                        }}
                      />
                      {filteredCustomers.length === 0 ? (
                        <FieldError className="mt-1">Nenhum colaborador disponível para a empresa selecionada.</FieldError>
                      ) : null}
                      <FieldError
                        errors={
                          form.formState.errors.requesterId
                            ? [{ message: form.formState.errors.requesterId.message }]
                            : []
                        }
                      />
                    </Field>

                    <Field>
                      <CategorySelectFields
                        tenantId={DEFAULT_TENANT_ID}
                        categoryId={categoryIdValue || null}
                        subcategoryId={subcategoryIdValue || null}
                        onCategoryChange={handleCategoryChange}
                        onSubcategoryChange={handleSubcategoryChange}
                        categoryRequired
                        subcategoryRequired
                        layout="stacked"
                      />
                      {form.formState.errors.categoryId?.message || form.formState.errors.subcategoryId?.message ? (
                        <FieldError className="mt-1 space-y-0.5">
                          <>
                            {form.formState.errors.categoryId?.message ? <div>{form.formState.errors.categoryId?.message}</div> : null}
                            {form.formState.errors.subcategoryId?.message ? <div>{form.formState.errors.subcategoryId?.message}</div> : null}
                          </>
                        </FieldError>
                      ) : null}
                    </Field>
                    <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 xl:gap-4">
                      <Field>
                        <FieldLabel>Prioridade</FieldLabel>
                        <Select value={priorityValue} onValueChange={(v) => form.setValue("priority", v as z.infer<typeof schema>["priority"])}>
                          <SelectTrigger className={selectTriggerClass}>
                            <SelectValue placeholder="Escolha a prioridade" />
                          </SelectTrigger>
                          <SelectContent className="rounded-xl border border-slate-200 bg-white text-neutral-800 shadow-md">
                            {(["LOW", "MEDIUM", "HIGH", "URGENT"] as const).map((option) => (
                              <SelectItem key={option} value={option} className={selectItemClass}>
                                <span className="inline-flex items-center gap-2">
                                  <PriorityIcon value={option} />
                                  {priorityStyles[option].label}
                                </span>
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </Field>
                      {/* Canal removido da UI: padrão MANUAL será enviado */}
                      <Field>
                        <FieldLabel>Fila</FieldLabel>
                        <Select value={queueValue} onValueChange={(v) => form.setValue("queueName", v === "NONE" ? null : v)}>
                          <SelectTrigger className={selectTriggerClass}>
                            <SelectValue placeholder="Sem fila" />
                          </SelectTrigger>
                          <SelectContent className="rounded-xl border border-slate-200 bg-white text-neutral-800 shadow-md">
                            <SelectItem value="NONE" className={selectItemClass}>
                              Sem fila
                            </SelectItem>
                            {queues.map((q) => (
                              <SelectItem key={q.id} value={q.name} className={selectItemClass}>
                                {q.name}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </Field>
                      {isVisitQueue ? (
                        <Field>
                          <FieldLabel className="flex items-center gap-1">
                            Data e horário da visita <span className="text-destructive">*</span>
                          </FieldLabel>
                          <div className="space-y-2">
                            <div className="grid gap-2 sm:grid-cols-[minmax(0,1fr)_140px]">
                              <Popover open={visitDatePickerOpen} onOpenChange={setVisitDatePickerOpen}>
                                <PopoverTrigger asChild>
                                  <button
                                    type="button"
                                    className={cn(
                                      "flex h-8 w-full items-center justify-between rounded-full border border-slate-300 bg-white px-3 text-left text-sm text-neutral-800 shadow-sm hover:bg-slate-50",
                                      !visitDate && "text-muted-foreground"
                                    )}
                                  >
                                    {visitDate
                                      ? format(visitDate, "dd/MM/yyyy", { locale: ptBR })
                                      : "Selecione a data"}
                                    <CalendarIcon className="ml-2 size-4 text-neutral-500" />
                                  </button>
                                </PopoverTrigger>
                                <PopoverContent className="w-auto p-0" align="start">
                                  <Calendar
                                    mode="single"
                                    selected={visitDate ?? undefined}
                                    onSelect={(date) => {
                                      if (!date) {
                                        form.setValue("visitDate", null, {
                                          shouldDirty: true,
                                          shouldTouch: true,
                                          shouldValidate: form.formState.isSubmitted,
                                        })
                                        form.setValue("visitTime", null, {
                                          shouldDirty: true,
                                          shouldTouch: true,
                                          shouldValidate: form.formState.isSubmitted,
                                        })
                                        return
                                      }
                                      const iso = date.toISOString().slice(0, 10)
                                      form.setValue("visitDate", iso, {
                                        shouldDirty: true,
                                        shouldTouch: true,
                                        shouldValidate: form.formState.isSubmitted,
                                      })
                                      setVisitDatePickerOpen(false)
                                    }}
                                    initialFocus
                                  />
                                </PopoverContent>
                              </Popover>
                              <div className="flex flex-col gap-1">
                                <TimePicker
                                  value={typeof visitTimeValue === "string" ? visitTimeValue : ""}
                                  onChange={(value) =>
                                    form.setValue("visitTime", value || null, {
                                      shouldDirty: true,
                                      shouldTouch: true,
                                      shouldValidate: form.formState.isSubmitted,
                                    })
                                  }
                                  stepMinutes={5}
                                  className="h-8 rounded-full border border-slate-300 bg-white text-sm font-medium text-neutral-800 shadow-sm"
                                />
                                <FieldError
                                  errors={
                                    form.formState.errors.visitTime
                                      ? [{ message: form.formState.errors.visitTime.message as string }]
                                      : []
                                  }
                                />
                              </div>
                            </div>
                            <FieldError
                              errors={
                                form.formState.errors.visitDate
                                  ? [{ message: form.formState.errors.visitDate.message as string }]
                                  : []
                              }
                            />
                          </div>
                        </Field>
                      ) : null}
                      <Field>
                        <FieldLabel>Responsável</FieldLabel>
                        <Select
                          value={assigneeSelectValue}
                          onValueChange={(value) =>
                            form.setValue("assigneeId", value === "NONE" ? null : value, {
                              shouldDirty: value !== assigneeValue,
                              shouldTouch: true,
                            })
                          }
                        >
                          <SelectTrigger className={selectTriggerClass}>
                            <SelectValue placeholder={staff.length === 0 ? "Carregando..." : "Selecione o responsável"} />
                          </SelectTrigger>
                          <SelectContent className="rounded-xl border border-slate-200 bg-white text-neutral-800 shadow-md">
                            <SelectItem value="NONE" className={selectItemClass}>
                              Sem responsável
                            </SelectItem>
                            {staff.map((member) => (
                              <SelectItem key={member._id} value={member._id} className={selectItemClass}>
                                {member.name}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </Field>
                    </div>
                  </div>

                {selectedForm.fields.length > 0 ? (
                  <div className="grid gap-4 rounded-xl border border-slate-200 bg-white px-4 py-4 sm:grid-cols-2 lg:col-span-2">
                    <p className="text-sm font-semibold text-neutral-800 sm:col-span-2">Informações adicionais</p>
                    {selectedForm.fields.map((field) => {
                      const value = customFieldValues[field.id]
                      const fieldId = `custom-field-${field.id}`
                      const isRequiredStar = field.required && field.key !== "colaborador_patrimonio"
                      const labelSuffix = isRequiredStar ? <span className="text-destructive">*</span> : null
                      const helpText = field.description ? (
                        <p className="text-xs text-neutral-500">{field.description}</p>
                      ) : null
                      const shouldUseTextarea = field.key.includes("observacao") || field.key.includes("permissao")
                      const spanClass = shouldUseTextarea || field.type === "boolean" ? "sm:col-span-2" : ""

                      if (field.type === "boolean") {
                        return (
                          <div
                            key={field.id}
                            className={cn(
                              "flex items-center gap-3 rounded-lg border border-slate-200 bg-slate-50 px-3 py-2",
                              spanClass,
                              "sm:col-span-2"
                            )}
                          >
                            <input
                              id={fieldId}
                              type="checkbox"
                              className="size-4 rounded border border-slate-300 text-[#00d6eb] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#00d6eb]/40"
                              checked={Boolean(value)}
                              onChange={(event) => handleCustomFieldChange(field, event.target.checked)}
                            />
                            <div className="flex flex-col">
                              <label htmlFor={fieldId} className="text-sm font-medium text-neutral-800">
                                {field.label} {labelSuffix}
                              </label>
                              {helpText}
                            </div>
                          </div>
                        )
                      }

                      if (field.type === "select") {
                        return (
                          <Field key={field.id} className={spanClass}>
                            <FieldLabel className="flex items-center gap-1">
                              {field.label} {labelSuffix}
                            </FieldLabel>
                            <Select
                              value={typeof value === "string" ? value : ""}
                              onValueChange={(selected) => handleCustomFieldChange(field, selected)}
                            >
                              <SelectTrigger className={selectTriggerClass}>
                                <SelectValue placeholder="Selecione" />
                              </SelectTrigger>
                              <SelectContent className="rounded-xl border border-slate-200 bg-white text-neutral-800 shadow-md">
                                {field.options.map((option) => (
                                  <SelectItem key={option.value} value={option.value} className={selectItemClass}>
                                    {option.label}
                                  </SelectItem>
                                ))}
                              </SelectContent>
                            </Select>
                            {helpText}
                          </Field>
                        )
                      }

                      if (field.type === "number") {
                        return (
                          <Field key={field.id} className={spanClass}>
                            <FieldLabel className="flex items-center gap-1">
                              {field.label} {labelSuffix}
                            </FieldLabel>
                            <Input
                              id={fieldId}
                              type="number"
                              inputMode="decimal"
                              value={typeof value === "number" || typeof value === "string" ? String(value) : ""}
                              onChange={(event) => handleCustomFieldChange(field, event.target.value)}
                            />
                            {helpText}
                          </Field>
                        )
                      }

                      if (field.type === "date") {
                        const parsedDate =
                          typeof value === "string" && value ? parseISO(value) : undefined
                        const isValidDate = Boolean(parsedDate && !Number.isNaN(parsedDate.getTime()))
                        return (
                          <Field key={field.id} className={spanClass}>
                            <FieldLabel className="flex items-center gap-1">
                              {field.label} {labelSuffix}
                            </FieldLabel>
                            <Popover
                              open={openCalendarField === field.id}
                              onOpenChange={(open) => setOpenCalendarField(open ? field.id : null)}
                            >
                              <PopoverTrigger asChild>
                                <Button
                                  type="button"
                                  variant="outline"
                                  className={cn(
                                    "w-full justify-between gap-2 text-left font-normal",
                                    !isValidDate && "text-muted-foreground"
                                  )}
                                >
                                  <span>
                                    {isValidDate
                                      ? format(parsedDate as Date, "dd/MM/yyyy", { locale: ptBR })
                                      : "Selecionar data"}
                                  </span>
                                  <CalendarIcon className="size-4 text-muted-foreground" aria-hidden="true" />
                                </Button>
                              </PopoverTrigger>
                              <PopoverContent className="w-auto p-0" align="start">
                                <Calendar
                                  mode="single"
                                  selected={isValidDate ? (parsedDate as Date) : undefined}
                                  onSelect={(selected) => {
                                    handleCustomFieldChange(
                                      field,
                                      selected ? format(selected, "yyyy-MM-dd") : ""
                                    )
                                    setOpenCalendarField(null)
                                  }}
                                  initialFocus
                                  captionLayout="dropdown"
                                  startMonth={new Date(1900, 0)}
                                  endMonth={new Date(new Date().getFullYear() + 5, 11)}
                                  locale={ptBR}
                                  timeZone={calendarTimeZone}
                                />
                              </PopoverContent>
                            </Popover>
                            {helpText}
                          </Field>
                        )
                      }

                      if (shouldUseTextarea) {
                        return (
                          <Field key={field.id} className={cn("flex-col", spanClass, "sm:col-span-2")}>
                            <FieldLabel className="flex items-center gap-1">
                              {field.label} {labelSuffix}
                            </FieldLabel>
                            <textarea
                              id={fieldId}
                              className="min-h-[90px] rounded-lg border border-slate-300 px-3 py-2 text-sm text-neutral-800 shadow-sm focus:border-neutral-900 focus:outline-none focus:ring-2 focus:ring-neutral-900/10"
                              value={typeof value === "string" ? value : ""}
                              onChange={(event) => handleCustomFieldChange(field, event.target.value)}
                            />
                            {helpText}
                          </Field>
                        )
                      }

                      return (
                        <Field key={field.id} className={spanClass}>
                          <FieldLabel className="flex items-center gap-1">
                            {field.label} {labelSuffix}
                          </FieldLabel>
                          <Input
                            id={fieldId}
                            value={typeof value === "string" ? value : ""}
                            onChange={(event) => handleCustomFieldChange(field, event.target.value)}
                          />
                          {helpText}
                        </Field>
                      )
                    })}
                  </div>
                ) : null}
                </FieldGroup>

                <div className="mt-6 rounded-2xl border border-slate-200 bg-white p-4 shadow-sm">
                  <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                    <div>
                      <p className="flex items-center gap-2 text-sm font-semibold text-neutral-900">
                        <ListChecks className="size-4 text-neutral-700" />
                        Checklist (opcional)
                      </p>
                      <p className="mt-1 text-xs text-neutral-500">
                        Itens obrigatórios bloqueiam o encerramento do ticket até serem concluídos.
                      </p>
                    </div>

                    {(checklistTemplates ?? []).length > 0 ? (
                      <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
                        <Select value={checklistTemplateToApply} onValueChange={setChecklistTemplateToApply}>
                          <SelectTrigger className="h-9 w-full sm:w-64">
                            <SelectValue placeholder="Aplicar template..." />
                          </SelectTrigger>
                          <SelectContent className="rounded-xl">
                            {(checklistTemplates ?? []).map((tpl) => (
                              <SelectItem key={tpl.id} value={String(tpl.id)}>
                                {tpl.name}
                                {tpl.company ? ` — ${tpl.company.name}` : ""}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                        <Button
                          type="button"
                          variant="outline"
                          className="h-9"
                          onClick={handleApplyChecklistTemplate}
                          disabled={
                            !checklistTemplateToApply.trim() ||
                            appliedChecklistTemplateIds.includes(checklistTemplateToApply.trim())
                          }
                        >
                          Aplicar
                        </Button>
                      </div>
                    ) : null}
                  </div>

                  {appliedChecklistTemplates.length > 0 ? (
                    <div className="mt-3 flex flex-wrap gap-2">
                      {appliedChecklistTemplates.map((tpl) => (
                        <Badge key={tpl.id} variant="secondary" className="flex items-center gap-2 rounded-full">
                          <span className="truncate">{tpl.name}</span>
                          <button
                            type="button"
                            className="text-xs text-neutral-600 hover:text-neutral-900"
                            onClick={() =>
                              setAppliedChecklistTemplateIds((prev) => prev.filter((id) => id !== String(tpl.id)))
                            }
                          >
                            ×
                          </button>
                        </Badge>
                      ))}
                    </div>
                  ) : null}

                  {checklistTemplatePreviewItems.length > 0 || manualChecklist.length > 0 ? (
                    <div className="mt-4 space-y-2">
                      {checklistTemplatePreviewItems.map((item) => (
                        <div
                          key={item.key}
                          className="flex items-start justify-between gap-3 rounded-xl border border-slate-200 bg-slate-50 px-3 py-2"
                        >
                          <div className="min-w-0">
                            <p className="truncate text-sm text-neutral-800" title={item.text}>
                              {item.text}
                            </p>
                            <div className="mt-1 flex flex-wrap items-center gap-2">
                              <Badge variant={item.required ? "secondary" : "outline"} className="rounded-full text-[11px]">
                                {item.required ? "Obrigatório" : "Opcional"}
                              </Badge>
                              <Badge variant="outline" className="rounded-full text-[11px]">
                                Template: {item.templateName}
                              </Badge>
                            </div>
                          </div>
                        </div>
                      ))}

                      {manualChecklist.map((item) => (
                        <div
                          key={item.id}
                          className="flex flex-col gap-2 rounded-xl border border-slate-200 bg-white px-3 py-2 sm:flex-row sm:items-center"
                        >
                          <Input
                            value={item.text}
                            onChange={(e) =>
                              setManualChecklist((prev) =>
                                prev.map((row) => (row.id === item.id ? { ...row, text: e.target.value } : row))
                              )
                            }
                            placeholder="Item do checklist..."
                            className="h-9 flex-1"
                          />
                          <label className="flex items-center gap-2 text-sm text-neutral-700">
                            <Checkbox
                              checked={item.required}
                              onCheckedChange={(checked) =>
                                setManualChecklist((prev) =>
                                  prev.map((row) =>
                                    row.id === item.id ? { ...row, required: Boolean(checked) } : row
                                  )
                                )
                              }
                            />
                            Obrigatório
                          </label>
                          <Button
                            type="button"
                            variant="ghost"
                            size="icon"
                            className="h-9 w-9 text-slate-500 hover:bg-red-50 hover:text-red-700"
                            onClick={() => setManualChecklist((prev) => prev.filter((row) => row.id !== item.id))}
                          >
                            <Trash2 className="size-4" />
                          </Button>
                        </div>
                      ))}
                    </div>
                  ) : (
                    <div className="mt-3 rounded-xl border border-dashed border-slate-200 p-4 text-sm text-neutral-600">
                      Adicione itens ou aplique um template para criar um checklist neste ticket.
                    </div>
                  )}

                  <div className="mt-4 flex flex-col gap-2 sm:flex-row sm:items-center">
                    <Input
                      value={checklistItemText}
                      onChange={(e) => setChecklistItemText(e.target.value)}
                      placeholder="Adicionar item do checklist..."
                      className="h-9 flex-1"
                      onKeyDown={(e) => {
                        if (e.key === "Enter") {
                          e.preventDefault()
                          handleAddChecklistItem()
                        }
                      }}
                    />
                    <label className="flex items-center gap-2 text-sm text-neutral-700">
                      <Checkbox
                        checked={checklistItemRequired}
                        onCheckedChange={(checked) => setChecklistItemRequired(Boolean(checked))}
                      />
                      Obrigatório
                    </label>
                    <Button type="button" onClick={handleAddChecklistItem} size="sm" className="ml-2 gap-2">
                      <Plus className="size-4" />
                      Adicionar
                    </Button>
                  </div>
                </div>
              </FieldSet>

              <div className="flex justify-end border-t border-slate-200 pt-5">
                <Button
                  type="submit"
                  disabled={loading}
                  className="inline-flex min-w-[140px] items-center justify-center gap-2 rounded-lg border border-black bg-black px-6 py-2 text-sm font-semibold text-white transition hover:bg-[#18181b]/85 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#18181b]/30 disabled:opacity-60"
                >
                  {loading ? (
                    <>
                      <Spinner className="me-2" /> Criando…
                    </>
                  ) : (
                    "Criar"
                  )}
                </Button>
              </div>
            </form>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  )
}
