import { format } from "date-fns"
import type { ComponentType, ReactNode } from "react"
import { ptBR } from "date-fns/locale"
import {
  IconCalendar,
  IconClockHour4,
  IconFolders,
  IconNote,
  IconPaperclip,
  IconSquareCheck,
  IconStar,
  IconUserCircle,
} from "@tabler/icons-react"

import type { TicketWithDetails } from "@/lib/schemas/ticket"
import { Card, CardContent } from "@/components/ui/card"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Separator } from "@/components/ui/separator"
import { TICKET_TIMELINE_LABELS } from "@/lib/ticket-timeline-labels"

const timelineIcons: Record<string, ComponentType<{ className?: string }>> = {
  CREATED: IconUserCircle,
  STATUS_CHANGED: IconSquareCheck,
  ASSIGNEE_CHANGED: IconUserCircle,
  COMMENT_ADDED: IconNote,
  COMMENT_EDITED: IconNote,
  WORK_STARTED: IconClockHour4,
  WORK_PAUSED: IconClockHour4,
  SUBJECT_CHANGED: IconNote,
  SUMMARY_CHANGED: IconNote,
  QUEUE_CHANGED: IconSquareCheck,
  PRIORITY_CHANGED: IconSquareCheck,
  ATTACHMENT_REMOVED: IconPaperclip,
  CATEGORY_CHANGED: IconFolders,
  MANAGER_NOTIFIED: IconUserCircle,
  VISIT_SCHEDULED: IconCalendar,
  CSAT_RECEIVED: IconStar,
  CSAT_RATED: IconStar,
}

const timelineLabels: Record<string, string> = TICKET_TIMELINE_LABELS

interface TicketTimelineProps {
  ticket: TicketWithDetails
}

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

  return (
    <Card className="rounded-2xl border border-slate-200 bg-white shadow-sm">
      <CardContent className="space-y-5 px-4 pb-6">
        {ticket.timeline.map((entry, index) => {
          const Icon = timelineIcons[entry.type] ?? IconClockHour4
          const isLast = index === ticket.timeline.length - 1
          return (
            <div key={entry.id} className="relative pl-11">
              {!isLast && (
                <span className="absolute left-[14px] top-6 h-full w-px bg-slate-200" aria-hidden />
              )}
              <span className="absolute left-0 top-0 flex size-8 items-center justify-center rounded-full border border-slate-200 bg-white text-neutral-700 shadow-sm">
                <Icon className="size-4" />
              </span>
              <div className="flex flex-col gap-2">
                <div className="flex flex-wrap items-center gap-x-3 gap-y-1">
                  <span className="text-sm font-semibold text-neutral-900">
                    {timelineLabels[entry.type] ?? entry.type}
                  </span>
                  {entry.payload?.actorName ? (
                    <span className="flex items-center gap-1 text-xs text-neutral-500">
                      <Avatar className="size-5 border border-slate-200">
                        <AvatarImage src={entry.payload?.actorAvatar as string | undefined} alt={String(entry.payload?.actorName ?? "")} />
                        <AvatarFallback>
                          {String(entry.payload?.actorName ?? "").split(" ").slice(0, 2).map((part: string) => part[0]).join("").toUpperCase()}
                        </AvatarFallback>
                      </Avatar>
                      por {String(entry.payload?.actorName ?? "")}
                    </span>
                  ) : null}
                  <span className="text-xs text-neutral-500">
                    {format(entry.createdAt, "dd MMM yyyy HH:mm", { locale: ptBR })}
                  </span>
                </div>
                {(() => {
                  const payload = (entry.payload || {}) as {
                    toLabel?: string
                    to?: string
                    assigneeName?: string
                    assigneeId?: string
                    queueName?: string
                    queueId?: string
                    requesterName?: string
                    authorName?: string
                    authorId?: string
                    actorName?: string
                    actorId?: string
                    from?: string
                    attachmentName?: string
                    sessionDurationMs?: number
                    categoryName?: string
                    subcategoryName?: string
                    pauseReason?: string
                    pauseReasonLabel?: string
                    pauseNote?: string
                    managerName?: string
                    managerUserName?: string
                    manager?: string
                    managerId?: string
                    managerUserId?: string
                    scheduledFor?: number | string
                    scheduledAt?: number | string
                    score?: number
                    rating?: number
                    maxScore?: number
                    max?: number
                  }

                  let message: ReactNode = null
                  if (entry.type === "STATUS_CHANGED" && (payload.toLabel || payload.to)) {
                    message = "Status alterado para " + (payload.toLabel || payload.to)
                  }
                  if (entry.type === "ASSIGNEE_CHANGED" && (payload.assigneeName || payload.assigneeId)) {
                    message = "Responsável alterado" + (payload.assigneeName ? " para " + payload.assigneeName : "")
                  }
                  if (entry.type === "QUEUE_CHANGED" && (payload.queueName || payload.queueId)) {
                    message = "Fila alterada" + (payload.queueName ? " para " + payload.queueName : "")
                  }
                  if (entry.type === "PRIORITY_CHANGED" && (payload.toLabel || payload.to)) {
                    message = "Prioridade alterada para " + (payload.toLabel || payload.to)
                  }
                  if (entry.type === "CREATED" && payload.requesterName) {
                    message = "Criado por " + payload.requesterName
                  }
                  if (entry.type === "COMMENT_ADDED" && (payload.authorName || payload.authorId)) {
                    message = "Comentário adicionado" + (payload.authorName ? " por " + payload.authorName : "")
                  }
                  if (entry.type === "COMMENT_EDITED" && (payload.actorName || payload.actorId || payload.authorName)) {
                    const name = payload.actorName ?? payload.authorName
                    message = "Comentário editado" + (name ? " por " + name : "")
                  }
                  if (entry.type === "SUBJECT_CHANGED" && (payload.to || payload.toLabel)) {
                    message = "Assunto alterado" + (payload.to ? " para \"" + payload.to + "\"" : "")
                  }
                  if (entry.type === "SUMMARY_CHANGED") {
                    message = "Resumo atualizado"
                  }
                  if (entry.type === "ATTACHMENT_REMOVED" && payload.attachmentName) {
                    message = `Anexo removido: ${payload.attachmentName}`
                  }
                  if (entry.type === "WORK_PAUSED") {
                    const parts: string[] = []
                    if (payload.pauseReasonLabel || payload.pauseReason) {
                      parts.push(`Motivo: ${payload.pauseReasonLabel ?? payload.pauseReason}`)
                    }
                    if (typeof payload.sessionDurationMs === "number") {
                      parts.push(`Tempo registrado: ${formatDuration(payload.sessionDurationMs)}`)
                    }
                    message = (
                      <div className="space-y-1">
                        <span>{parts.length > 0 ? parts.join(" • ") : "Atendimento pausado"}</span>
                        {payload.pauseNote ? (
                          <span className="block text-xs text-neutral-500">Observação: {payload.pauseNote}</span>
                        ) : null}
                      </div>
                    )
                  }
                  if (entry.type === "CATEGORY_CHANGED") {
                    if (payload.categoryName || payload.subcategoryName) {
                      message = `Categoria alterada para ${payload.categoryName ?? ""}${
                        payload.subcategoryName ? ` • ${payload.subcategoryName}` : ""
                      }`
                    } else {
                      message = "Categoria removida"
                    }
                  }
                  if (entry.type === "MANAGER_NOTIFIED") {
                    const manager =
                      payload.managerName ??
                      payload.managerUserName ??
                      payload.manager ??
                      payload.managerId ??
                      payload.managerUserId
                    message = manager ? `Gestor notificado: ${manager}` : "Gestor notificado"
                  }
                  if (entry.type === "VISIT_SCHEDULED") {
                    const scheduledRaw = payload.scheduledFor ?? payload.scheduledAt
                    let formatted: string | null = null
                    if (typeof scheduledRaw === "number" || typeof scheduledRaw === "string") {
                      const date = new Date(scheduledRaw)
                      if (!Number.isNaN(date.getTime())) {
                        formatted = format(date, "dd MMM yyyy HH:mm", { locale: ptBR })
                      }
                    }
                    message = formatted ? `Visita agendada para ${formatted}` : "Visita agendada"
                  }
                  if (entry.type === "CSAT_RECEIVED") {
                    message = "CSAT recebido"
                  }
                  if (entry.type === "CSAT_RATED") {
                    const score = typeof payload.score === "number" ? payload.score : payload.rating
                    const maxScore =
                      typeof payload.maxScore === "number"
                        ? payload.maxScore
                        : typeof payload.max === "number"
                          ? payload.max
                          : undefined
                    message =
                      typeof score === "number"
                        ? `CSAT avaliado: ${score}${typeof maxScore === "number" ? `/${maxScore}` : ""}`
                        : "CSAT avaliado"
                  }
                  if (!message) return null

                  return (
                    <div className="rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm text-neutral-600">{message}</div>
                  )
                })()}
              </div>
            </div>
          )
        })}
        <Separator className="bg-slate-200" />
      </CardContent>
    </Card>
  )
}
