"use client"

import { useEffect, useMemo, useState } from "react"
import Link from "next/link"
import { usePaginatedQuery, useQuery } from "convex/react"
import { format, formatDistanceToNowStrict } from "date-fns"
import { ptBR } from "date-fns/locale"
import { IconUserOff } from "@tabler/icons-react"

import type { Id } from "@/convex/_generated/dataModel"
import { api } from "@/convex/_generated/api"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { DatePicker } from "@/components/ui/date-picker"
import { cn } from "@/lib/utils"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Spinner } from "@/components/ui/spinner"
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyTitle } from "@/components/ui/empty"
import { TicketStatusBadge } from "@/components/tickets/status-badge"
import type { TicketPriority, TicketStatus } from "@/lib/schemas/ticket"
import { EmptyIndicator } from "@/components/ui/empty-indicator"

type DeviceTicketHistoryItem = {
  id: string
  reference: number
  subject: string
  status: TicketStatus
  priority: TicketPriority | string
  updatedAt: number
  createdAt: number
  queue: string | null
  requester: { name: string | null; email: string | null } | null
  assignee: { name: string | null; email: string | null } | null
}

type DeviceTicketsHistoryArgs = {
  machineId: Id<"machines">
  status?: "open" | "resolved"
  priority?: string
  search?: string
  from?: number
  to?: number
}

type DeviceTicketsHistoryStats = {
  total: number
  openCount: number
  resolvedCount: number
}

type PeriodPreset = "7d" | "30d" | "90d" | "year" | "all" | "custom"

function startOfDayMs(date: Date) {
  const copy = new Date(date)
  copy.setHours(0, 0, 0, 0)
  return copy.getTime()
}

function endOfDayMs(date: Date) {
  const copy = new Date(date)
  copy.setHours(23, 59, 59, 999)
  return copy.getTime()
}

function parseDateInput(value: string) {
  if (!value) return null
  const parsed = new Date(`${value}T00:00:00`)
  if (Number.isNaN(parsed.getTime())) {
    return null
  }
  return parsed
}

function computeRange(preset: PeriodPreset, customFrom: string, customTo: string) {
  if (preset === "all") {
    return { from: null, to: null }
  }
  if (preset === "custom") {
    const fromDate = parseDateInput(customFrom)
    const toDate = parseDateInput(customTo)
    return {
      from: fromDate ? startOfDayMs(fromDate) : null,
      to: toDate ? endOfDayMs(toDate) : null,
    }
  }

  const now = new Date()
  const end = endOfDayMs(now)
  const start = new Date(now)

  switch (preset) {
    case "7d":
      start.setDate(start.getDate() - 6)
      break
    case "30d":
      start.setDate(start.getDate() - 29)
      break
    case "90d":
      start.setDate(start.getDate() - 89)
      break
    case "year":
      start.setMonth(0, 1)
      start.setHours(0, 0, 0, 0)
      break
    default:
      break
  }

  return { from: startOfDayMs(start), to: end }
}

function formatRelativeTime(timestamp?: number | null) {
  if (!timestamp || timestamp <= 0) return "—"
  return formatDistanceToNowStrict(timestamp, { addSuffix: true, locale: ptBR })
}

function formatAbsoluteTime(timestamp?: number | null) {
  if (!timestamp || timestamp <= 0) return "—"
  return format(timestamp, "dd/MM/yyyy HH:mm", { locale: ptBR })
}

function getPriorityMeta(priority: TicketPriority | string | null | undefined) {
  const normalized = (priority ?? "MEDIUM").toString().toUpperCase()
  switch (normalized) {
    case "LOW":
      return { label: "Baixa", badgeClass: "bg-emerald-100 text-emerald-700 border border-emerald-200" }
    case "MEDIUM":
      return { label: "Média", badgeClass: "bg-sky-100 text-sky-700 border border-sky-200" }
    case "HIGH":
      return { label: "Alta", badgeClass: "bg-amber-100 text-amber-700 border border-amber-200" }
    case "URGENT":
      return { label: "Urgente", badgeClass: "bg-rose-100 text-rose-700 border border-rose-200" }
    default:
      return { label: normalized, badgeClass: "bg-slate-100 text-slate-700 border border-slate-200" }
  }
}

export function DeviceTicketsHistoryClient({ tenantId: _tenantId, deviceId }: { tenantId: string; deviceId: string }) {
  const [statusFilter, setStatusFilter] = useState<"all" | "open" | "resolved">("all")
  const [priorityFilter, setPriorityFilter] = useState<string>("ALL")
  const [periodPreset, setPeriodPreset] = useState<PeriodPreset>("90d")
  const [customFrom, setCustomFrom] = useState<string>("")
  const [customTo, setCustomTo] = useState<string>("")
  const [searchValue, setSearchValue] = useState<string>("")
  const [debouncedSearch, setDebouncedSearch] = useState<string>("")

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedSearch(searchValue.trim())
    }, 300)
    return () => clearTimeout(timer)
  }, [searchValue])

  useEffect(() => {
    if (periodPreset !== "custom") {
      setCustomFrom("")
      setCustomTo("")
    }
  }, [periodPreset])

  const range = useMemo(() => computeRange(periodPreset, customFrom, customTo), [periodPreset, customFrom, customTo])

  const queryArgs = useMemo(() => {
    const args: DeviceTicketsHistoryArgs = {
      machineId: deviceId as Id<"machines">,
    }
    if (statusFilter !== "all") {
      args.status = statusFilter
    }
    if (priorityFilter !== "ALL") {
      args.priority = priorityFilter
    }
    if (debouncedSearch) {
      args.search = debouncedSearch
    }
    if (range.from !== null) {
      args.from = range.from
    }
    if (range.to !== null) {
      args.to = range.to
    }
    return args
  }, [debouncedSearch, deviceId, priorityFilter, range.from, range.to, statusFilter])

  const { results: tickets, status: paginationStatus, loadMore } = usePaginatedQuery(
    api.devices.listTicketsHistory,
    queryArgs,
    { initialNumItems: 25 }
  )

  const stats = useQuery(api.devices.getTicketsHistoryStats, queryArgs) as DeviceTicketsHistoryStats | undefined
  const totalTickets = stats?.total ?? 0
  const openTickets = stats?.openCount ?? 0
  const resolvedTickets = stats?.resolvedCount ?? 0

  const isLoadingFirstPage = paginationStatus === "LoadingFirstPage"
  const isLoadingMore = paginationStatus === "LoadingMore"
  const canLoadMore = paginationStatus === "CanLoadMore"

  const resetFilters = () => {
    setStatusFilter("all")
    setPriorityFilter("ALL")
    setPeriodPreset("90d")
    setCustomFrom("")
    setCustomTo("")
    setSearchValue("")
    setDebouncedSearch("")
  }

  return (
    <div className="space-y-6">
      <section className="grid gap-3 sm:grid-cols-3">
        <div className="rounded-2xl border border-slate-200 bg-white px-4 py-4 shadow-sm">
          <p className="text-xs font-medium uppercase tracking-wide text-neutral-500">Chamados no período</p>
          <p className="pt-1 text-2xl font-semibold text-neutral-900">
            {stats ? (
              totalTickets
            ) : (
              <span className="inline-flex items-center gap-2 text-sm text-neutral-500">
                <Spinner className="size-4 text-neutral-400" /> Atualizando...
              </span>
            )}
          </p>
        </div>
        <div className="rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-4 shadow-sm">
          <p className="text-xs font-medium uppercase tracking-wide text-emerald-700">Em aberto</p>
          <p className="pt-1 text-2xl font-semibold text-emerald-900">{stats ? openTickets : "—"}</p>
        </div>
        <div className="rounded-2xl border border-slate-200 bg-slate-50 px-4 py-4 shadow-sm">
          <p className="text-xs font-medium uppercase tracking-wide text-neutral-600">Resolvidos</p>
          <p className="pt-1 text-2xl font-semibold text-neutral-900">{stats ? resolvedTickets : "—"}</p>
        </div>
      </section>

      <section className="rounded-2xl border border-slate-200 bg-white p-4 shadow-sm lg:p-6">
        <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
          <div className="flex w-full flex-col gap-3 sm:flex-row">
            <Input
              value={searchValue}
              onChange={(event) => setSearchValue(event.target.value)}
              placeholder="Buscar por assunto, #ID, solicitante ou responsável"
              className="sm:max-w-sm"
            />
            <Select value={statusFilter} onValueChange={(value) => setStatusFilter(value as typeof statusFilter)}>
              <SelectTrigger className="sm:w-[160px]">
                <SelectValue placeholder="Status" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">Todos os status</SelectItem>
                <SelectItem value="open">Em aberto</SelectItem>
                <SelectItem value="resolved">Resolvidos</SelectItem>
              </SelectContent>
            </Select>
            <Select value={priorityFilter} onValueChange={(value) => setPriorityFilter(value)}>
              <SelectTrigger className="sm:w-[160px]">
                <SelectValue placeholder="Prioridade" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="ALL">Todas as prioridades</SelectItem>
                <SelectItem value="URGENT">Urgente</SelectItem>
                <SelectItem value="HIGH">Alta</SelectItem>
                <SelectItem value="MEDIUM">Média</SelectItem>
                <SelectItem value="LOW">Baixa</SelectItem>
              </SelectContent>
            </Select>
          </div>
          <div className="flex flex-col gap-3 sm:flex-row sm:items-center">
            <Select value={periodPreset} onValueChange={(value) => setPeriodPreset(value as PeriodPreset)}>
              <SelectTrigger className="sm:w-[200px]">
                <SelectValue placeholder="Período" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="7d">Últimos 7 dias</SelectItem>
                <SelectItem value="30d">Últimos 30 dias</SelectItem>
                <SelectItem value="90d">Últimos 90 dias</SelectItem>
                <SelectItem value="year">Este ano</SelectItem>
                <SelectItem value="all">Desde sempre</SelectItem>
                <SelectItem value="custom">Personalizado</SelectItem>
              </SelectContent>
            </Select>
            {periodPreset === "custom" ? (
              <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
                <DatePicker
                  value={customFrom}
                  onChange={(value) => setCustomFrom(value ?? "")}
                  className="sm:w-[160px]"
                  placeholder="Início"
                />
                <DatePicker
                  value={customTo}
                  onChange={(value) => setCustomTo(value ?? "")}
                  className="sm:w-[160px]"
                  placeholder="Fim"
                />
              </div>
            ) : null}
            <Button variant="outline" size="sm" onClick={resetFilters}>
              Limpar filtros
            </Button>
          </div>
        </div>
      </section>

      <section className="rounded-2xl border border-slate-200 bg-white p-0 shadow-sm">
        {isLoadingFirstPage ? (
          <div className="flex items-center justify-center gap-2 py-12">
            <Spinner className="size-5 text-neutral-500" />
            <span className="text-sm text-neutral-600">Carregando chamados...</span>
          </div>
        ) : tickets.length === 0 ? (
          <Empty className="m-4 border-dashed">
            <EmptyHeader>
              <EmptyTitle>Nenhum chamado encontrado</EmptyTitle>
              <EmptyDescription>
                Ajuste os filtros ou expanda o período para visualizar o histórico de chamados desta dispositivo.
              </EmptyDescription>
            </EmptyHeader>
            <EmptyContent>
              <Button variant="outline" size="sm" onClick={resetFilters}>
                Limpar filtros
              </Button>
            </EmptyContent>
          </Empty>
        ) : (
          <>
            <div className="overflow-x-auto">
              <Table>
                <TableHeader>
                  <TableRow className="border-b border-slate-200 bg-slate-50/60">
                    <TableHead className="min-w-[260px] text-xs font-semibold uppercase tracking-wide text-neutral-500">
                      Ticket
                    </TableHead>
                    <TableHead className="w-[140px] text-xs font-semibold uppercase tracking-wide text-neutral-500">
                      Status
                    </TableHead>
                    <TableHead className="w-[140px] text-xs font-semibold uppercase tracking-wide text-neutral-500">
                      Prioridade
                    </TableHead>
                    <TableHead className="w-[160px] text-xs font-semibold uppercase tracking-wide text-neutral-500">
                      Última atualização
                    </TableHead>
                    <TableHead className="w-[200px] text-xs font-semibold uppercase tracking-wide text-neutral-500">
                      Responsável
                    </TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {tickets.map((ticket) => {
                    const priorityMeta = getPriorityMeta(ticket.priority)
                    const requesterLabel = ticket.requester?.name ?? ticket.requester?.email ?? "Solicitante não informado"
                    const updatedLabel = formatRelativeTime(ticket.updatedAt)
                    const updatedAbsolute = formatAbsoluteTime(ticket.updatedAt)
                    return (
                      <TableRow key={ticket.id} className="border-b border-slate-100 hover:bg-slate-50/70">
                        <TableCell className="align-top">
                          <div className="flex flex-col gap-1">
                            <Link
                              href={`/tickets/${ticket.id}`}
                              className="text-sm font-semibold text-neutral-900 underline-offset-4 hover:underline"
                            >
                              #{ticket.reference} · {ticket.subject}
                            </Link>
                            <div className="flex flex-wrap items-center gap-2 text-xs text-neutral-500">
                              <span>{requesterLabel}</span>
                              {ticket.queue ? (
                                <span className="inline-flex items-center rounded-full bg-slate-200/70 px-2 py-0.5 text-[11px] font-medium text-neutral-600">
                                  {ticket.queue}
                                </span>
                              ) : null}
                              <span className="text-neutral-400">Aberto em {formatAbsoluteTime(ticket.createdAt)}</span>
                            </div>
                          </div>
                        </TableCell>
                        <TableCell className="align-top">
                          <TicketStatusBadge status={ticket.status} className="h-7 px-3 text-xs font-semibold" />
                        </TableCell>
                        <TableCell className="align-top">
                          <Badge className={cn("rounded-full px-3 py-1 text-xs font-semibold", priorityMeta.badgeClass)}>
                            {priorityMeta.label}
                          </Badge>
                        </TableCell>
                        <TableCell className="align-top">
                          <div className="flex flex-col text-xs text-neutral-600">
                            <span className="font-medium text-neutral-800">{updatedLabel}</span>
                            <span className="text-[11px] text-neutral-400">{updatedAbsolute}</span>
                          </div>
                        </TableCell>
                        <TableCell className="align-top">
                          <div className="flex flex-col items-start text-sm text-neutral-700">
                            {ticket.assignee ? (
                              <>
                                <span>{ticket.assignee.name ?? ticket.assignee.email ?? "—"}</span>
                                {ticket.assignee.email ? (
                                  <span className="text-xs text-neutral-400">{ticket.assignee.email}</span>
                                ) : null}
                              </>
                            ) : (
                              <EmptyIndicator
                                icon={IconUserOff}
                                label="Sem responsável"
                                className="h-7 w-7 border-neutral-200 bg-transparent text-neutral-400"
                              />
                            )}
                          </div>
                        </TableCell>
                      </TableRow>
                    )
                  })}
                </TableBody>
              </Table>
            </div>
            <div className="border-t border-slate-200 px-4 py-4 text-center">
              {canLoadMore || isLoadingMore ? (
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => loadMore(25)}
                  disabled={isLoadingMore}
                  className="inline-flex items-center gap-2"
                >
                  {isLoadingMore ? (
                    <>
                      <Spinner className="size-4 text-neutral-500" />
                      Carregando...
                    </>
                  ) : (
                    "Carregar mais"
                  )}
                </Button>
              ) : (
                <span className="text-xs text-neutral-500">
                  Todos os chamados filtrados foram exibidos.
                </span>
              )}
            </div>
          </>
        )}
      </section>
    </div>
  )
}
