"use client"

import { useEffect, useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import type { Doc, Id } from "@/convex/_generated/dataModel"
import type { TicketPriority, TicketQueueSummary } from "@/lib/schemas/ticket"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { useAuth } from "@/lib/auth-client"
import { api } from "@/convex/_generated/api"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { RichTextEditor, sanitizeEditorHtml } from "@/components/ui/rich-text-editor"
import { Spinner } from "@/components/ui/spinner"
import { Badge } from "@/components/ui/badge"
import { cn } from "@/lib/utils"
import { PriorityIcon, priorityBadgeClass, priorityItemClass, priorityTriggerClass } from "@/components/tickets/priority-select"
import { CategorySelectFields } from "@/components/tickets/category-select"
import { priorityStyles } from "@/lib/ticket-priority-style"

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

const ALL_COMPANIES_VALUE = "__all__"
const NO_COMPANY_VALUE = "__no_company__"
const NO_REQUESTER_VALUE = "__no_requester__"


export default function NewTicketPage() {
  const router = useRouter()
  const { convexUserId, isStaff, role, session, machineContext } = useAuth()
  const sessionUser = session?.user ?? null
  const queuesEnabled = Boolean(isStaff && convexUserId)
  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 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 [subject, setSubject] = useState("")
  const [priority, setPriority] = useState<TicketPriority>("MEDIUM")
  const [channel, setChannel] = useState("MANUAL")
  const [queueName, setQueueName] = useState<string | null>(null)
  const [assigneeId, setAssigneeId] = useState<string | null>(null)
  const [description, setDescription] = useState("")
  const [loading, setLoading] = useState(false)
  const [subjectError, setSubjectError] = useState<string | null>(null)
  const [categoryId, setCategoryId] = useState<string | null>(null)
  const [subcategoryId, setSubcategoryId] = useState<string | null>(null)
  const [categoryError, setCategoryError] = useState<string | null>(null)
  const [subcategoryError, setSubcategoryError] = useState<string | null>(null)
  const [descriptionError, setDescriptionError] = useState<string | null>(null)
  const [assigneeInitialized, setAssigneeInitialized] = useState(false)

  const [companyFilter, setCompanyFilter] = useState<string>(ALL_COMPANIES_VALUE)
  const [requesterId, setRequesterId] = useState<string | null>(convexUserId)
  const [requesterError, setRequesterError] = useState<string | null>(null)
  const [customersInitialized, setCustomersInitialized] = useState(false)

  const queueOptions = useMemo(() => queues.map((q) => q.name), [queues])
  const assigneeSelectValue = assigneeId ?? "NONE"

  const companyOptions = useMemo(() => {
    const map = new Map<string, { id: string; name: string; isAvulso?: boolean }>()
    companies.forEach((company) => {
      map.set(company.id, { id: company.id, name: company.name, isAvulso: false })
    })
    customers.forEach((customer) => {
      if (customer.companyId && !map.has(customer.companyId)) {
        map.set(customer.companyId, {
          id: customer.companyId,
          name: customer.companyName ?? "Empresa sem nome",
          isAvulso: customer.companyIsAvulso,
        })
      }
    })
    const includeNoCompany = customers.some((customer) => !customer.companyId)
    const result: Array<{ id: string; name: string; isAvulso?: boolean }> = [
      { id: ALL_COMPANIES_VALUE, name: "Todas as empresas" },
    ]
    if (includeNoCompany) {
      result.push({ id: NO_COMPANY_VALUE, name: "Sem empresa" })
    }
    const sorted = Array.from(map.values()).sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))
    return [...result, ...sorted]
  }, [companies, customers])

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

  useEffect(() => {
    if (customersInitialized) return
    if (!customers.length) return
    let initialRequester = requesterId
    if (!initialRequester || !customers.some((customer) => customer.id === initialRequester)) {
      if (convexUserId && customers.some((customer) => customer.id === convexUserId)) {
        initialRequester = convexUserId
      } else {
        initialRequester = customers[0]?.id ?? null
      }
    }
    if (initialRequester) {
      setRequesterId(initialRequester)
      const selected = customers.find((customer) => customer.id === initialRequester)
      if (selected?.companyId) {
        setCompanyFilter(selected.companyId)
      } else if (selected) {
        setCompanyFilter(NO_COMPANY_VALUE)
      }
    }
    setCustomersInitialized(true)
  }, [customersInitialized, customers, requesterId, convexUserId])

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

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


  useEffect(() => {
    if (assigneeInitialized) return
    if (!convexUserId) return
    setAssigneeId(convexUserId)
    setAssigneeInitialized(true)
  }, [assigneeInitialized, convexUserId])

  // Default queue to "Chamados" if available
  useEffect(() => {
    if (queueName) return
    const hasChamados = queueOptions.includes("Chamados")
    if (hasChamados) setQueueName("Chamados")
  }, [queueOptions, queueName])

  const allowTicketMentions = useMemo(() => {
    const normalized = (role ?? "").toLowerCase()
    return normalized === "admin" || normalized === "agent" || normalized === "collaborator"
  }, [role])

  async function submit(event: React.FormEvent) {
    event.preventDefault()
    if (!convexUserId || loading) return

    const trimmedSubject = subject.trim()
    if (trimmedSubject.length < 3) {
      setSubjectError("Informe um assunto com pelo menos 3 caracteres.")
      return
    }
    setSubjectError(null)

    if (!categoryId) {
      setCategoryError("Selecione uma categoria.")
      return
    }
    if (!subcategoryId) {
      setSubcategoryError("Selecione uma categoria secundária.")
      return
    }

    const sanitizedDescription = sanitizeEditorHtml(description)
    const plainDescription = sanitizedDescription.replace(/<[^>]*>/g, "").trim()
    if (plainDescription.length === 0) {
      setDescriptionError("Descreva o contexto do chamado.")
      return
    }
    setDescriptionError(null)

    if (!requesterId) {
      setRequesterError("Selecione um solicitante.")
      toast.error("Selecione um solicitante para o chamado.")
      return
    }

    setLoading(true)
    toast.loading("Criando ticket...", { id: "create-ticket" })
    try {
      const selQueue = queues.find((q) => q.name === queueName)
      const queueId = selQueue ? (selQueue.id as Id<"queues">) : undefined
      const assigneeToSend = assigneeId ? (assigneeId as Id<"users">) : undefined
      const requesterToSend = requesterId as Id<"users">
      const id = await create({
        actorId: convexUserId as Id<"users">,
        tenantId: DEFAULT_TENANT_ID,
        subject: trimmedSubject,
        priority,
        channel,
        queueId,
        requesterId: requesterToSend,
        assigneeId: assigneeToSend,
        categoryId: categoryId as Id<"ticketCategories">,
        subcategoryId: subcategoryId as Id<"ticketSubcategories">,
      })
      if (plainDescription.length > 0) {
        await addComment({
          ticketId: id as Id<"tickets">,
          authorId: convexUserId as Id<"users">,
          visibility: "INTERNAL",
          body: sanitizedDescription,
          attachments: [],
        })
      }
      toast.success("Ticket criado!", { id: "create-ticket" })
      router.replace(`/tickets/${id}`)
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível criar o ticket.", { id: "create-ticket" })
    } finally {
      setLoading(false)
    }
  }

  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"

  return (
    <div className="mx-auto max-w-3xl px-6 py-8">
      <Card className="rounded-2xl border border-slate-200 shadow-sm">
        <CardHeader className="space-y-2">
          <CardTitle className="text-2xl font-semibold text-neutral-900">Novo ticket</CardTitle>
          <CardDescription className="text-sm text-neutral-600">Preencha as informações básicas para abrir um chamado.</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={submit} className="space-y-6">
            <div className="space-y-2">
              <label className="flex items-center gap-1 text-sm font-medium text-neutral-700" htmlFor="subject">
                Assunto <span className="text-red-500">*</span>
              </label>
              <Input
                id="subject"
                value={subject}
                onChange={(event) => {
                  setSubject(event.target.value)
                  if (subjectError) setSubjectError(null)
                }}
                placeholder="Ex.: Erro 500 no portal"
                aria-invalid={subjectError ? "true" : undefined}
              />
              {subjectError ? <p className="text-xs font-medium text-red-500">{subjectError}</p> : null}
            </div>
            <div className="space-y-2">
              <label className="flex items-center gap-1 text-sm font-medium text-neutral-700">
                Descrição <span className="text-red-500">*</span>
              </label>
              <RichTextEditor
                value={description}
                onChange={(html) => {
                  setDescription(html)
                  if (descriptionError) {
                    const plain = html.replace(/<[^>]*>/g, "").trim()
                    if (plain.length > 0) {
                      setDescriptionError(null)
                    }
                  }
                }}
                placeholder="Detalhe o problema, passos para reproduzir, links, etc."
                ticketMention={{ enabled: allowTicketMentions }}
              />
              {descriptionError ? <p className="text-xs font-medium text-red-500">{descriptionError}</p> : null}
            </div>
            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <label className="text-sm font-medium text-neutral-700" htmlFor="company">
                  Empresa
                </label>
                <Select
                  value={companyFilter}
                  onValueChange={(value) => {
                    setCompanyFilter(value)
                    setRequesterError(null)
                  }}
                >
                  <SelectTrigger className={selectTriggerClass}>
                    <SelectValue placeholder="Selecionar empresa" />
                  </SelectTrigger>
                  <SelectContent className="rounded-xl border border-slate-200 bg-white text-neutral-800 shadow-sm">
                    {companyOptions.map((option) => (
                      <SelectItem key={option.id} value={option.id} className={selectItemClass}>
                        {option.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <label className="flex items-center gap-1 text-sm font-medium text-neutral-700" htmlFor="requester">
                  Solicitante <span className="text-red-500">*</span>
                </label>
                <Select
                  value={requesterId ?? NO_REQUESTER_VALUE}
                  onValueChange={(value) => {
                    if (value === NO_REQUESTER_VALUE) {
                      setRequesterId(null)
                    } else {
                      setRequesterId(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-xl border border-slate-200 bg-white text-neutral-800 shadow-sm">
                    {filteredCustomers.length === 0 ? (
                      <SelectItem value={NO_REQUESTER_VALUE} disabled className={selectItemClass}>
                        Nenhum usuário disponível
                      </SelectItem>
                    ) : (
                      filteredCustomers.map((customer) => (
                        <SelectItem key={customer.id} value={customer.id} className={selectItemClass}>
                          <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 ? (
                  <p className="text-xs text-neutral-500">
                    Nenhum colaborador disponível para a empresa selecionada.
                  </p>
                ) : null}
                {requesterError ? <p className="text-xs font-medium text-red-500">{requesterError}</p> : null}
              </div>
            </div>

            <div className="space-y-2">
              <CategorySelectFields
                tenantId={DEFAULT_TENANT_ID}
                categoryId={categoryId}
                subcategoryId={subcategoryId}
                onCategoryChange={(value) => {
                  setCategoryId(value)
                  setCategoryError(null)
                }}
                onSubcategoryChange={(value) => {
                  setSubcategoryId(value)
                  setSubcategoryError(null)
                }}
                categoryLabel="Categoria primária *"
                subcategoryLabel="Categoria secundária *"
              />
              {categoryError || subcategoryError ? (
                <div className="text-xs font-medium text-red-500">
                  {categoryError ? <div>{categoryError}</div> : null}
                  {subcategoryError ? <div>{subcategoryError}</div> : null}
                </div>
              ) : null}
            </div>
            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
              <div className="space-y-2">
                <span className="text-sm font-medium text-neutral-700">Prioridade</span>
                <Select value={priority} onValueChange={(value) => setPriority(value as TicketPriority)}>
                  <SelectTrigger className={cn(priorityTriggerClass, "w-full justify-between") }>
                    <SelectValue>
                      <Badge className={cn(priorityBadgeClass, priorityStyles[priority]?.badgeClass)}>
                        <PriorityIcon value={priority} />
                        {priorityStyles[priority]?.label ?? priority}
                      </Badge>
                    </SelectValue>
                  </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={priorityItemClass}>
                        <span className="inline-flex items-center gap-2">
                          <PriorityIcon value={option} />
                          {priorityStyles[option].label}
                        </span>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <span className="text-sm font-medium text-neutral-700">Canal</span>
                <Select value={channel} onValueChange={setChannel}>
                  <SelectTrigger className={selectTriggerClass}>
                    <SelectValue placeholder="Canal" />
                  </SelectTrigger>
                  <SelectContent className="rounded-xl border border-slate-200 bg-white text-neutral-800 shadow-md">
                    <SelectItem value="EMAIL" className={selectItemClass}>
                      E-mail
                    </SelectItem>
                    <SelectItem value="WHATSAPP" className={selectItemClass}>
                      WhatsApp
                    </SelectItem>
                    <SelectItem value="CHAT" className={selectItemClass}>
                      Chat
                    </SelectItem>
                    <SelectItem value="PHONE" className={selectItemClass}>
                      Telefone
                    </SelectItem>
                    <SelectItem value="API" className={selectItemClass}>
                      API
                    </SelectItem>
                    <SelectItem value="MANUAL" className={selectItemClass}>
                      Manual
                    </SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <span className="text-sm font-medium text-neutral-700">Fila</span>
                <Select value={queueName ?? "NONE"} onValueChange={(value) => setQueueName(value === "NONE" ? null : value)}>
                  <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>
                    {queueOptions.map((name) => (
                      <SelectItem key={name} value={name} className={selectItemClass}>
                        {name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <span className="text-sm font-medium text-neutral-700">Responsável</span>
                <Select value={assigneeSelectValue} onValueChange={(value) => setAssigneeId(value === "NONE" ? null : value)}>
                  <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>
              </div>
            </div>
            <div className="flex justify-end">
              <Button
                type="submit"
                className="min-w-[120px] rounded-lg border border-black bg-black px-4 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={loading}
              >
                {loading ? (
                  <>
                    <Spinner className="me-2" />
                    Criando...
                  </>
                ) : (
                  "Criar"
                )}
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>
    </div>
  )
}
