"use client"

import { useMemo, useState } from "react"
import { useQuery, useMutation } from "convex/react"
import { format, formatDistanceToNow } from "date-fns"
import { ptBR } from "date-fns/locale"
import { MessageCircle } from "lucide-react"
import { toast } from "sonner"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { DEFAULT_TENANT_ID } from "@/lib/constants"
import { mapTicketWithDetailsFromServer } from "@/lib/mappers/ticket"
import type { TicketWithDetails } from "@/lib/schemas/ticket"
import { useAuth } from "@/lib/auth-client"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty"
import { Skeleton } from "@/components/ui/skeleton"
import { Textarea } from "@/components/ui/textarea"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { sanitizeEditorHtml } from "@/components/ui/rich-text-editor"

const statusLabel: Record<TicketWithDetails["status"], string> = {
  PENDING: "Pendente",
  AWAITING_ATTENDANCE: "Aguardando atendimento",
  PAUSED: "Pausado",
  RESOLVED: "Resolvido",
}

const priorityLabel: Record<TicketWithDetails["priority"], string> = {
  LOW: "Baixa",
  MEDIUM: "Média",
  HIGH: "Alta",
  URGENT: "Urgente",
}

const priorityTone: Record<TicketWithDetails["priority"], string> = {
  LOW: "bg-slate-100 text-slate-600",
  MEDIUM: "bg-sky-100 text-sky-700",
  HIGH: "bg-amber-100 text-amber-700",
  URGENT: "bg-rose-100 text-rose-700",
}

const timelineLabels: Record<string, string> = {
  CREATED: "Chamado criado",
  STATUS_CHANGED: "Status atualizado",
  ASSIGNEE_CHANGED: "Responsável alterado",
  COMMENT_ADDED: "Novo comentário",
  COMMENT_EDITED: "Comentário editado",
  ATTACHMENT_REMOVED: "Anexo removido",
  QUEUE_CHANGED: "Fila atualizada",
}

function toHtmlFromText(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>`
}

interface PortalTicketDetailProps {
  ticketId: string
}

export function PortalTicketDetail({ ticketId }: PortalTicketDetailProps) {
  const { convexUserId, session } = useAuth()
  const addComment = useMutation(api.tickets.addComment)
  const [comment, setComment] = useState("")

  const ticketRaw = useQuery(
    api.tickets.getById,
    convexUserId
      ? {
          tenantId: session?.user.tenantId ?? DEFAULT_TENANT_ID,
          id: ticketId as Id<"tickets">,
          viewerId: convexUserId as Id<"users">,
        }
      : "skip"
  )

  const ticket = useMemo(() => {
    if (!ticketRaw) return null
    return mapTicketWithDetailsFromServer(ticketRaw)
  }, [ticketRaw])

  if (ticketRaw === undefined) {
    return (
      <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
        <CardHeader className="px-5 py-5">
          <CardTitle className="text-lg font-semibold text-neutral-900">Carregando ticket...</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3 px-5 pb-6">
          <Skeleton className="h-6 w-2/3" />
          <Skeleton className="h-4 w-full" />
          <Skeleton className="h-4 w-5/6" />
        </CardContent>
      </Card>
    )
  }

  if (!ticket) {
    return (
      <Empty>
        <EmptyHeader>
          <EmptyMedia variant="icon">
            <span className="text-2xl">🔍</span>
          </EmptyMedia>
          <EmptyTitle className="text-neutral-900">Ticket não encontrado</EmptyTitle>
          <EmptyDescription className="text-neutral-600">
            Verifique o endereço ou retorne à lista de chamados.
          </EmptyDescription>
        </EmptyHeader>
      </Empty>
    )
  }

  const createdAt = format(ticket.createdAt, "dd 'de' MMMM 'de' yyyy 'às' HH:mm", { locale: ptBR })
  const updatedAgo = formatDistanceToNow(ticket.updatedAt, { addSuffix: true, locale: ptBR })

  async function handleSubmit(event: React.FormEvent) {
    event.preventDefault()
    if (!convexUserId || !comment.trim() || !ticket) return
    const toastId = "portal-add-comment"
    toast.loading("Enviando comentário...", { id: toastId })
    try {
      const htmlBody = sanitizeEditorHtml(toHtmlFromText(comment.trim()))
      await addComment({
        ticketId: ticket.id as Id<"tickets">,
        authorId: convexUserId as Id<"users">,
        visibility: "PUBLIC",
        body: htmlBody,
        attachments: [],
      })
      setComment("")
      toast.success("Comentário enviado!", { id: toastId })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível enviar o comentário.", { id: toastId })
    }
  }

  return (
    <div className="space-y-6">
      <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
        <CardHeader className="px-5 pb-3 pt-6">
          <div className="flex flex-wrap items-start justify-between gap-4">
            <div>
              <p className="text-sm text-neutral-500">Ticket #{ticket.reference}</p>
              <h1 className="mt-1 text-2xl font-semibold text-neutral-900">{ticket.subject}</h1>
              {ticket.summary ? (
                <p className="mt-2 max-w-3xl text-sm text-neutral-600">{ticket.summary}</p>
              ) : null}
            </div>
            <div className="flex flex-col items-end gap-2 text-sm">
              <Badge className="rounded-full bg-neutral-900 px-3 py-1 text-xs font-semibold uppercase text-white">
                {statusLabel[ticket.status]}
              </Badge>
              <Badge className={`rounded-full px-3 py-1 text-xs font-semibold uppercase ${priorityTone[ticket.priority]}`}>
                {priorityLabel[ticket.priority]}
              </Badge>
            </div>
          </div>
        </CardHeader>
        <CardContent className="grid gap-4 border-t border-slate-100 px-5 py-5 text-sm text-neutral-700 sm:grid-cols-2">
          <DetailItem label="Fila" value={ticket.queue ?? "Sem fila"} />
          <DetailItem label="Categoria" value={ticket.category?.name ?? "Não classificada"} />
          <DetailItem label="Solicitante" value={ticket.requester.name} subtitle={ticket.requester.email} />
          <DetailItem label="Responsável" value={ticket.assignee?.name ?? "Equipe de suporte"} />
          <DetailItem label="Criado em" value={createdAt} />
          <DetailItem label="Última atualização" value={updatedAgo} />
        </CardContent>
      </Card>

      <div className="grid gap-6 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]">
        <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
          <CardHeader className="flex flex-row items-center justify-between px-5 py-4">
            <CardTitle className="flex items-center gap-2 text-lg font-semibold text-neutral-900">
              <MessageCircle className="size-5 text-neutral-500" /> Conversas
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-6 px-5 pb-6">
            <form onSubmit={handleSubmit} className="space-y-3">
              <label htmlFor="comment" className="text-sm font-medium text-neutral-800">
                Enviar uma mensagem para a equipe
              </label>
              <Textarea
                id="comment"
                value={comment}
                onChange={(event) => setComment(event.target.value)}
                placeholder="Descreva o que aconteceu, envie atualizações ou compartilhe novas informações."
                className="min-h-[120px] resize-y rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-neutral-800 shadow-sm focus-visible:border-neutral-900 focus-visible:ring-neutral-900/20"
              />
              <div className="flex justify-end">
                <Button type="submit" className="rounded-full bg-neutral-900 px-6 text-sm font-semibold text-white hover:bg-neutral-900/90">
                  Enviar comentário
                </Button>
              </div>
            </form>

            <div className="space-y-5">
              {ticket.comments.length === 0 ? (
                <Empty>
                  <EmptyHeader>
                    <EmptyMedia variant="icon">
                      <MessageCircle className="size-5 text-neutral-500" />
                    </EmptyMedia>
                    <EmptyTitle className="text-neutral-900">Nenhum comentário ainda</EmptyTitle>
                    <EmptyDescription className="text-neutral-600">
                      Registre a primeira atualização acima.
                    </EmptyDescription>
                  </EmptyHeader>
                </Empty>
              ) : (
                ticket.comments.map((commentItem) => {
                  const initials = commentItem.author.name
                    .split(" ")
                    .slice(0, 2)
                    .map((part) => part.charAt(0).toUpperCase())
                    .join("")
                  const createdAgo = formatDistanceToNow(commentItem.createdAt, {
                    addSuffix: true,
                    locale: ptBR,
                  })
                  return (
                    <div key={commentItem.id} className="rounded-xl border border-slate-100 bg-slate-50/70 p-4">
                      <div className="flex items-center justify-between gap-3">
                        <div className="flex items-center gap-3">
                          <Avatar className="size-9 border border-slate-200">
                            <AvatarImage src={commentItem.author.avatarUrl} alt={commentItem.author.name} />
                            <AvatarFallback>{initials}</AvatarFallback>
                          </Avatar>
                          <div className="flex flex-col">
                            <span className="text-sm font-semibold text-neutral-900">{commentItem.author.name}</span>
                            <span className="text-xs text-neutral-500">{createdAgo}</span>
                          </div>
                        </div>
                        <Badge variant="outline" className="rounded-full border-dashed px-3 py-1 text-[11px] uppercase text-neutral-600">
                          {commentItem.visibility === "PUBLIC" ? "Público" : "Interno"}
                        </Badge>
                      </div>
                      <div
                        className="prose prose-sm mt-3 max-w-none text-neutral-800"
                        dangerouslySetInnerHTML={{ __html: sanitizeEditorHtml(commentItem.body ?? "") }}
                      />
                    </div>
                  )
                })
              )}
            </div>
          </CardContent>
        </Card>

        <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
          <CardHeader className="px-5 py-4">
            <CardTitle className="text-lg font-semibold text-neutral-900">Linha do tempo</CardTitle>
          </CardHeader>
          <CardContent className="space-y-5 px-5 pb-6 text-sm text-neutral-700">
            {ticket.timeline.length === 0 ? (
              <p className="text-sm text-neutral-500">Nenhum evento registrado ainda.</p>
            ) : (
              ticket.timeline
                .slice()
                .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
                .map((event) => {
                  const label = timelineLabels[event.type] ?? event.type
                  const when = formatDistanceToNow(event.createdAt, { addSuffix: true, locale: ptBR })
                  return (
                    <div key={event.id} className="flex flex-col gap-1 rounded-xl border border-slate-100 bg-slate-50/50 p-3">
                      <span className="text-sm font-semibold text-neutral-900">{label}</span>
                      <span className="text-xs text-neutral-500">{when}</span>
                    </div>
                  )
                })
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  )
}

interface DetailItemProps {
  label: string
  value: string
  subtitle?: string | null
}

function DetailItem({ label, value, subtitle }: DetailItemProps) {
  return (
    <div className="rounded-xl border border-dashed border-slate-200 bg-white/60 px-4 py-3 shadow-[0_1px_2px_rgba(15,23,42,0.04)]">
      <p className="text-xs uppercase tracking-wide text-neutral-500">{label}</p>
      <p className="text-sm font-medium text-neutral-900">{value}</p>
      {subtitle ? <p className="text-xs text-neutral-500">{subtitle}</p> : null}
    </div>
  )
}
