"use client"

import { useEffect, useMemo, useRef, useState } from "react"
import Link from "next/link"
import { formatDistanceStrict } from "date-fns"
import { ptBR } from "date-fns/locale"
import { LayoutGrid } from "lucide-react"
import { IconBuildingOff, IconCategory, IconUserOff } from "@tabler/icons-react"

import type { Ticket } from "@/lib/schemas/ticket"
import { Badge } from "@/components/ui/badge"
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyTitle } from "@/components/ui/empty"
import { cn } from "@/lib/utils"
import { PrioritySelect } from "@/components/tickets/priority-select"
import { getTicketStatusChipClass, getTicketStatusLabel } from "@/lib/ticket-status-style"
import { EmptyIndicator } from "@/components/ui/empty-indicator"
import { deriveServerOffset, toServerTimestamp } from "@/components/tickets/ticket-timer.utils"

type TicketsBoardProps = {
  tickets: Ticket[]
  enteringIds?: Set<string>
}

const SECOND = 1_000
const MINUTE = 60 * SECOND
const HOUR = 60 * MINUTE
const DAY = 24 * HOUR

function getTimestamp(value: Date | number | string | null | undefined) {
  if (value == null) return null
  if (typeof value === "number") {
    return Number.isFinite(value) ? value : null
  }
  const parsed = value instanceof Date ? value.getTime() : new Date(value).getTime()
  return Number.isFinite(parsed) ? parsed : null
}

function getNextDelay(diff: number) {
  if (diff < MINUTE) {
    return SECOND
  }

  if (diff < HOUR) {
    const pastMinute = diff % MINUTE
    return pastMinute === 0 ? MINUTE : MINUTE - pastMinute
  }

  if (diff < DAY) {
    const pastHour = diff % HOUR
    return pastHour === 0 ? HOUR : HOUR - pastHour
  }

  const pastDay = diff % DAY
  return pastDay === 0 ? DAY : DAY - pastDay
}

function formatUpdated(date: Date | number | string, now: number) {
  const timestamp = getTimestamp(date)
  if (timestamp === null) return "—"
  return formatDistanceStrict(timestamp, now, { addSuffix: true, locale: ptBR })
}

function formatQueueLabel(queue?: string | null) {
  if (!queue) {
    return { label: "Sem fila", title: "Sem fila" }
  }
  const normalized = queue.trim().toLowerCase()
  if (normalized.startsWith("laboratorio")) {
    return { label: "Lab", title: queue }
  }
  return { label: queue, title: queue }
}

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

export function TicketsBoard({ tickets, enteringIds }: TicketsBoardProps) {
  const [now, setNow] = useState(() => Date.now())
  const serverOffsetRef = useRef<number>(0)

  const ticketTimestamps = useMemo(() => {
    return tickets
      .map((ticket) => getTimestamp(ticket.updatedAt))
      .filter((value): value is number => value !== null)
  }, [tickets])

  useEffect(() => {
    if (ticketTimestamps.length === 0) {
      return
    }

    let minDelay = DAY
    for (const timestamp of ticketTimestamps) {
      const diff = Math.abs(now - timestamp)
      const candidate = Math.max(SECOND, getNextDelay(diff))
      if (candidate < minDelay) {
        minDelay = candidate
      }
    }

    const timeoutId = window.setTimeout(() => setNow(Date.now()), minDelay)
    return () => window.clearTimeout(timeoutId)
  }, [ticketTimestamps, now])

  useEffect(() => {
    const candidates = tickets
      .map((ticket) =>
        typeof ticket.workSummary?.serverNow === "number" ? ticket.workSummary.serverNow : null
      )
      .filter((value): value is number => value !== null)
    if (candidates.length === 0) return
    const latestServerNow = candidates[candidates.length - 1]
    serverOffsetRef.current = deriveServerOffset({
      currentOffset: serverOffsetRef.current,
      localNow: Date.now(),
      serverNow: latestServerNow,
    })
  }, [tickets])

  const getWorkedMs = (ticket: Ticket) => {
    const base = ticket.workSummary?.totalWorkedMs ?? 0
    const activeStart = ticket.workSummary?.activeSession?.startedAt
    if (activeStart instanceof Date) {
      const alignedNow = toServerTimestamp(now, serverOffsetRef.current)
      return base + Math.max(0, alignedNow - activeStart.getTime())
    }
    return base
  }

  if (!tickets.length) {
    return (
      <div className="rounded-3xl border border-slate-200 bg-white p-12 text-center shadow-sm">
        <Empty>
          <EmptyHeader>
            <LayoutGrid className="mx-auto size-9 text-neutral-400" />
          </EmptyHeader>
          <EmptyContent>
            <EmptyTitle>Nenhum ticket encontrado</EmptyTitle>
            <EmptyDescription>
              Ajuste os filtros ou crie um novo ticket para visualizar aqui na visão em quadro.
            </EmptyDescription>
          </EmptyContent>
        </Empty>
      </div>
    )
  }

  return (
    <div className="grid gap-6 sm:grid-cols-2 xl:grid-cols-3">
      {tickets.map((ticket) => {
        const isEntering = enteringIds?.has(ticket.id)
        const queueDisplay = formatQueueLabel(ticket.queue)
        const updatedTimestamp = getTimestamp(ticket.updatedAt)
        const updatedAbsoluteLabel = updatedTimestamp
          ? new Date(updatedTimestamp).toLocaleString("pt-BR", {
              dateStyle: "short",
              timeStyle: "short",
            })
          : "—"

        return (
          <Link
            key={ticket.id}
            href={`/tickets/${ticket.id}`}
            className={cn(
              "group flex h-full flex-col rounded-3xl border border-slate-200 bg-white p-6 shadow-sm transition hover:-translate-y-1 hover:border-slate-300 hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-300",
              isEntering ? "recent-ticket-enter" : "",
            )}
          >
            <div className="flex w-full flex-col gap-3">
              <div className="flex w-full items-center justify-between gap-4">
                <Badge
                  variant="outline"
                  className="rounded-full border-slate-200 bg-white px-4 py-2 text-sm font-semibold tracking-tight text-neutral-700"
                >
                  #{ticket.reference}
                </Badge>
                <span className="text-right text-sm font-semibold text-neutral-900" title={queueDisplay.title}>
                  {queueDisplay.label}
                </span>
              </div>
              <div className="flex w-full items-center justify-between gap-4">
                <span
                  className={cn(
                    "inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-semibold transition",
                    getTicketStatusChipClass(ticket.status),
                  )}
                >
                  {getTicketStatusLabel(ticket.status)}
                </span>
                <div
                  className="relative z-[1] flex justify-end"
                  onPointerDown={(event) => event.stopPropagation()}
                  onClick={(event) => event.stopPropagation()}
                  onKeyDown={(event) => event.stopPropagation()}
                >
                  <PrioritySelect
                    className="min-w-[7rem]"
                    badgeClassName="h-9 px-4 shadow-sm"
                    ticketId={ticket.id}
                    value={ticket.priority}
                  />
                </div>
              </div>
            </div>

            <div className="mt-4 rounded-2xl border border-slate-200 bg-white px-4 py-3 text-center shadow-sm">
              <h3 className="line-clamp-2 text-lg font-semibold text-neutral-900">
                {ticket.subject || "Sem assunto"}
              </h3>
            </div>

            <div className="mt-4 flex flex-1 flex-col gap-5 rounded-2xl border border-slate-200 bg-white p-4 shadow-sm">
              <dl className="grid grid-cols-1 gap-4 text-sm text-neutral-600 sm:grid-cols-2">
                <div className="flex flex-col gap-1">
                  <dt className="text-xs font-semibold uppercase tracking-wide text-neutral-400">
                    Empresa
                  </dt>
                  <dd className="text-neutral-700">
                    {ticket.company?.name ?? (
                      <EmptyIndicator
                        icon={IconBuildingOff}
                        label="Nenhuma empresa vinculada"
                        className="h-7 w-7 border-neutral-200 bg-transparent text-neutral-400"
                      />
                    )}
                  </dd>
                </div>
                <div className="flex flex-col gap-1">
                  <dt className="text-xs font-semibold uppercase tracking-wide text-neutral-400">
                    Responsável
                  </dt>
                  <dd className="text-neutral-700">
                    {ticket.assignee?.name ?? (
                      <EmptyIndicator
                        icon={IconUserOff}
                        label="Sem responsável"
                        className="h-7 w-7 border-neutral-200 bg-transparent text-neutral-400"
                      />
                    )}
                  </dd>
                </div>
                <div className="flex flex-col gap-1">
                  <dt className="text-xs font-semibold uppercase tracking-wide text-neutral-400">
                    Solicitante
                  </dt>
                  <dd className="text-neutral-700">
                    {ticket.requester?.name ?? ticket.requester?.email ?? "—"}
                  </dd>
                </div>
                <div className="flex flex-col gap-1">
                  <dt className="text-xs font-semibold uppercase tracking-wide text-neutral-400">
                    Criado em
                  </dt>
                  <dd className="text-neutral-700">
                    {(() => {
                      const createdTimestamp = getTimestamp(ticket.createdAt)
                      return createdTimestamp
                        ? new Date(createdTimestamp).toLocaleDateString("pt-BR")
                        : "—"
                    })()}
                  </dd>
                </div>
              </dl>

              <div className="mt-auto flex flex-wrap items-center justify-between gap-3 border-t border-slate-200 pt-4 text-sm text-neutral-600">
                <span className="text-neutral-700">
                  Categoria:{" "}
                  {ticket.category?.name ? (
                    <span className="font-semibold text-neutral-900">{ticket.category.name}</span>
                  ) : (
                    <EmptyIndicator
                      icon={IconCategory}
                      label="Sem categoria"
                      className="ml-2 h-7 w-7 border-neutral-200 bg-transparent text-neutral-400"
                    />
                  )}
                </span>
                <span className="text-xs text-neutral-500">
                  Tempo:{" "}
                  <span className="font-semibold text-neutral-900">
                    {formatDuration(getWorkedMs(ticket))}
                  </span>
                  {ticket.workSummary?.activeSession ? (
                    <span className="ml-1 text-[11px] font-medium text-emerald-600">Em andamento</span>
                  ) : null}
                </span>
              </div>
            </div>
          </Link>
        )
      })}
    </div>
  )
}
